home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / mpeg / video.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  109KB  |  4,041 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.  
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  *
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  *
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code that implements
  22.  * the video decoder model.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <assert.h>
  28.  
  29. #ifndef MIPS
  30. #include <sys/time.h>
  31. #else
  32. #include <sys/types.h>
  33. #include <sys/system.h>
  34. #endif
  35.  
  36. #include "decoders.h"
  37. #include "video.h"
  38. #include "util.h"
  39. #include "proto.h"
  40.  
  41. /* Declarations of functions. */
  42. static void ReconIMBlock();
  43. static void ReconPMBlock();
  44. static void ReconBMBlock();
  45. static void ReconBiMBlock();
  46. static void ReconSkippedBlock();
  47. static void DoPictureDisplay();
  48. static int ParseSeqHead();
  49. static int ParseGOP();
  50. static int ParsePicture();
  51. static int ParseSlice();
  52. static int ParseMacroBlock();
  53. static void ProcessSkippedPFrameMBlocks();
  54. static void ProcessSkippedBFrameMBlocks();
  55.  
  56. extern int ditherType;
  57. char *ditherFlags;
  58.  
  59. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  60.  
  61. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  62.  
  63. /* Declare global pointer to vid stream used for current decoding. */
  64.  
  65. VidStream *curVidStream = NULL;
  66.  
  67. /* Set up array for fast conversion from zig zag order to row/column
  68.    coordinates.
  69. */
  70.  
  71. int zigzag[64][2] = {
  72.   0, 0, 1, 0, 0, 1, 0, 2, 1, 1, 2, 0, 3, 0, 2, 1, 1, 2, 0, 3, 0, 4, 1, 3,
  73.   2, 2, 3, 1, 4, 0, 5, 0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 5, 0, 6, 1, 5, 2, 4,
  74.   3, 3, 4, 2, 5, 1, 6, 0, 7, 0, 6, 1, 5, 2, 4, 3, 3, 4, 2, 5, 1, 6, 0, 7,
  75.   1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6, 2, 7, 1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6,
  76.   2, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 5, 7, 6, 6,
  77. 7, 5, 7, 6, 6, 7, 7, 7};
  78. /* Array mapping zigzag to array pointer offset. */
  79.  
  80. int zigzag_direct[64] = {
  81.   0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
  82.   19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
  83.   42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
  84. 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
  85. /* Set up array for fast conversion from row/column coordinates to
  86.    zig zag order.
  87. */
  88.  
  89. int scan[8][8] = {
  90.   {0, 1, 5, 6, 14, 15, 27, 28},
  91.   {2, 4, 7, 13, 16, 26, 29, 42},
  92.   {3, 8, 12, 17, 25, 30, 41, 43},
  93.   {9, 11, 18, 24, 31, 40, 44, 53},
  94.   {10, 19, 23, 32, 39, 45, 52, 54},
  95.   {20, 22, 33, 38, 46, 51, 55, 60},
  96.   {21, 34, 37, 47, 50, 56, 59, 61},
  97. {35, 36, 48, 49, 57, 58, 62, 63}};
  98. /* Initialize P and B skip flags. */
  99.  
  100. static int No_P_Flag = 0;
  101. static int No_B_Flag = 0;
  102.  
  103. /* Max lum, chrom indices for illegal block checking. */
  104.  
  105. static int lmaxx;
  106. static int lmaxy;
  107. static int cmaxx;
  108. static int cmaxy;
  109.  
  110. /*
  111.  * We use a lookup table to make sure values stay in the 0..255 range.
  112.  * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this
  113.  * table the "crop table".
  114.  * MAX_NEG_CROP is the maximum neg/pos value we can handle.
  115.  */
  116.  
  117. #define MAX_NEG_CROP 384
  118. #define NUM_CROP_ENTRIES (256+2*MAX_NEG_CROP)
  119. #define assertCrop(x)    assert(((x) >= -MAX_NEG_CROP) && \
  120.                    ((x) <= 256+MAX_NEG_CROP))
  121. static unsigned char cropTbl[NUM_CROP_ENTRIES];
  122.  
  123. /*
  124.   The following accounts for time and size  spent in various parsing acitivites
  125.   if ANALYSIS has been defined.
  126. */
  127.  
  128. #ifdef ANALYSIS
  129.  
  130.  
  131. unsigned int bitCount = 0;
  132.  
  133. int showmb_flag = 0;
  134. int showEachFlag = 0;
  135.  
  136. typedef struct {
  137.   int frametype;
  138.   unsigned int totsize;
  139.   unsigned int number;
  140.   unsigned int i_mbsize;
  141.   unsigned int p_mbsize;
  142.   unsigned int b_mbsize;
  143.   unsigned int bi_mbsize;
  144.   unsigned int i_mbnum;
  145.   unsigned int p_mbnum;
  146.   unsigned int b_mbnum;
  147.   unsigned int bi_mbnum;
  148.   unsigned int i_mbcbp[64];
  149.   unsigned int p_mbcbp[64];
  150.   unsigned int b_mbcbp[64];
  151.   unsigned int bi_mbcbp[64];
  152.   unsigned int i_mbcoeff[64];
  153.   unsigned int p_mbcoeff[64];
  154.   unsigned int b_mbcoeff[64];
  155.   unsigned int bi_mbcoeff[64];
  156.   double tottime;
  157. } Statval;
  158.  
  159. Statval stat_a[4];
  160. unsigned int pictureSizeCount;
  161. unsigned int mbSizeCount;
  162. unsigned int *mbCBPPtr, *mbCoeffPtr, *mbSizePtr;
  163. unsigned int cacheHit[8][8];
  164. unsigned int cacheMiss[8][8];
  165.  
  166. static void
  167. init_stat_struct(astat)
  168.   Statval *astat;
  169. {
  170.   int j;
  171.  
  172.   astat->frametype = 0;
  173.   astat->totsize = 0;
  174.   astat->number = 0;
  175.   astat->i_mbsize = 0;
  176.   astat->p_mbsize = 0;
  177.   astat->b_mbsize = 0;
  178.   astat->bi_mbsize = 0;
  179.   astat->i_mbnum = 0;
  180.   astat->p_mbnum = 0;
  181.   astat->b_mbnum = 0;
  182.   astat->bi_mbnum = 0;
  183.  
  184.   for (j = 0; j < 64; j++) {
  185.  
  186.     astat->i_mbcbp[j] = 0;
  187.     astat->p_mbcbp[j] = 0;
  188.     astat->b_mbcbp[j] = 0;
  189.     astat->bi_mbcbp[j] = 0;
  190.     astat->i_mbcoeff[j] = 0;
  191.     astat->p_mbcoeff[j] = 0;
  192.     astat->b_mbcoeff[j] = 0;
  193.     astat->bi_mbcoeff[j] = 0;
  194.   }
  195.   astat->tottime = 0.0;
  196. }
  197.  
  198. void
  199. init_stats()
  200. {
  201.   int i, j;
  202.  
  203.   for (i = 0; i < 4; i++) {
  204.     init_stat_struct(&(stat_a[i]));
  205.     stat_a[i].frametype = i;
  206.   }
  207.  
  208.   for (i = 0; i < 8; i++) {
  209.     for (j = 0; j < 8; j++) {
  210.       cacheHit[i][j] = 0;
  211.       cacheMiss[i][j] = 0;
  212.     }
  213.   }
  214.  
  215.   bitCount = 0;
  216. }
  217.  
  218. static void
  219. PrintOneStat()
  220. {
  221.   int i;
  222.  
  223.   printf("\n");
  224.   switch (stat_a[0].frametype) {
  225.   case I_TYPE:
  226.     printf("I FRAME\n");
  227.     break;
  228.   case P_TYPE:
  229.     printf("P FRAME\n");
  230.     break;
  231.   case B_TYPE:
  232.     printf("B FRAME\n");
  233.     break;
  234.   }
  235.  
  236.   printf("Size: %d bytes + %d bits\n", stat_a[0].totsize / 8, stat_a[0].totsize % 8);
  237.   if (stat_a[0].i_mbnum > 0) {
  238.     printf("\tI Macro Block Stats:\n");
  239.     printf("\t%d I Macroblocks\n", stat_a[0].i_mbnum);
  240.     printf("\tAvg. Size: %d bytes + %d bits\n",
  241.        stat_a[0].i_mbsize / (8 * stat_a[0].i_mbnum),
  242.        (stat_a[0].i_mbsize * stat_a[0].i_mbnum) % 8);
  243.     printf("\t\tCoded Block Pattern Histogram:\n");
  244.     for (i = 0; i < 64; i += 8) {
  245.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcbp[i],
  246.          stat_a[0].i_mbcbp[i + 1], stat_a[0].i_mbcbp[i + 2], stat_a[0].i_mbcbp[i + 3],
  247.          stat_a[0].i_mbcbp[i + 4], stat_a[0].i_mbcbp[i + 5], stat_a[0].i_mbcbp[i + 6],
  248.          stat_a[0].i_mbcbp[i + 7]);
  249.     }
  250.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  251.     for (i = 0; i < 64; i += 8) {
  252.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcoeff[i],
  253.          stat_a[0].i_mbcoeff[i + 1], stat_a[0].i_mbcoeff[i + 2],
  254.          stat_a[0].i_mbcoeff[i + 3], stat_a[0].i_mbcoeff[i + 4],
  255.          stat_a[0].i_mbcoeff[i + 5], stat_a[0].i_mbcoeff[i + 6],
  256.          stat_a[0].i_mbcoeff[i + 7]);
  257.     }
  258.   }
  259.   if (stat_a[0].p_mbnum > 0) {
  260.     printf("\tP Macro Block Stats:\n");
  261.     printf("\t%d P Macroblocks\n", stat_a[0].p_mbnum);
  262.     printf("\tAvg. Size: %d bytes + %d bits\n",
  263.        stat_a[0].p_mbsize / (8 * stat_a[0].p_mbnum),
  264.        (stat_a[0].p_mbsize / stat_a[0].p_mbnum) % 8);
  265.     printf("\t\tCoded Block Pattern Histogram:\n");
  266.     for (i = 0; i < 64; i += 8) {
  267.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcbp[i],
  268.          stat_a[0].p_mbcbp[i + 1], stat_a[0].p_mbcbp[i + 2], stat_a[0].p_mbcbp[i + 3],
  269.          stat_a[0].p_mbcbp[i + 4], stat_a[0].p_mbcbp[i + 5], stat_a[0].p_mbcbp[i + 6],
  270.          stat_a[0].p_mbcbp[i + 7]);
  271.     }
  272.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  273.     for (i = 0; i < 64; i += 8) {
  274.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcoeff[i],
  275.          stat_a[0].p_mbcoeff[i + 1], stat_a[0].p_mbcoeff[i + 2],
  276.          stat_a[0].p_mbcoeff[i + 3], stat_a[0].p_mbcoeff[i + 4],
  277.          stat_a[0].p_mbcoeff[i + 5], stat_a[0].p_mbcoeff[i + 6],
  278.          stat_a[0].p_mbcoeff[i + 7]);
  279.     }
  280.   }
  281.   if (stat_a[0].b_mbnum > 0) {
  282.     printf("\tB Macro Block Stats:\n");
  283.     printf("\t%d B Macroblocks\n", stat_a[0].b_mbnum);
  284.     printf("\tAvg. Size: %d bytes + %d bits\n",
  285.        stat_a[0].b_mbsize / (8 * stat_a[0].b_mbnum),
  286.        (stat_a[0].b_mbsize / stat_a[0].b_mbnum) % 8);
  287.     printf("\t\tCoded Block Pattern Histogram:\n");
  288.     for (i = 0; i < 64; i += 8) {
  289.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcbp[i],
  290.          stat_a[0].b_mbcbp[i + 1], stat_a[0].b_mbcbp[i + 2], stat_a[0].b_mbcbp[i + 3],
  291.          stat_a[0].b_mbcbp[i + 4], stat_a[0].b_mbcbp[i + 5], stat_a[0].b_mbcbp[i + 6],
  292.          stat_a[0].b_mbcbp[i + 7]);
  293.     }
  294.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  295.     for (i = 0; i < 64; i += 8) {
  296.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcoeff[i],
  297.          stat_a[0].b_mbcoeff[i + 1], stat_a[0].b_mbcoeff[i + 2],
  298.          stat_a[0].b_mbcoeff[i + 3], stat_a[0].b_mbcoeff[i + 4],
  299.          stat_a[0].b_mbcoeff[i + 5], stat_a[0].b_mbcoeff[i + 6],
  300.          stat_a[0].b_mbcoeff[i + 7]);
  301.     }
  302.   }
  303.   if (stat_a[0].bi_mbnum > 0) {
  304.     printf("\tBi Macro Block Stats:\n");
  305.     printf("\t%d Bi Macroblocks\n", stat_a[0].bi_mbnum);
  306.     printf("\tAvg. Size: %d bytes + %d bits\n",
  307.        stat_a[0].bi_mbsize / (8 * stat_a[0].bi_mbnum),
  308.        (stat_a[0].bi_mbsize * stat_a[0].bi_mbnum) % 8);
  309.     printf("\t\tCoded Block Pattern Histogram:\n");
  310.     for (i = 0; i < 64; i += 8) {
  311.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcbp[i],
  312.          stat_a[0].bi_mbcbp[i + 1], stat_a[0].bi_mbcbp[i + 2], stat_a[0].bi_mbcbp[i + 3],
  313.          stat_a[0].bi_mbcbp[i + 4], stat_a[0].bi_mbcbp[i + 5], stat_a[0].bi_mbcbp[i + 6],
  314.          stat_a[0].bi_mbcbp[i + 7]);
  315.     }
  316.     printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  317.     for (i = 0; i < 64; i += 8) {
  318.       printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcoeff[i],
  319.          stat_a[0].bi_mbcoeff[i + 1], stat_a[0].bi_mbcoeff[i + 2],
  320.          stat_a[0].bi_mbcoeff[i + 3], stat_a[0].bi_mbcoeff[i + 4],
  321.          stat_a[0].bi_mbcoeff[i + 5], stat_a[0].bi_mbcoeff[i + 6],
  322.          stat_a[0].bi_mbcoeff[i + 7]);
  323.     }
  324.   }
  325.   printf("\nTime to Decode: %g secs.\n", stat_a[0].tottime);
  326.   printf("****************\n");
  327. }
  328.  
  329. void
  330. PrintAllStats()
  331. {
  332.   int i, j;
  333.   unsigned int supertot, supernum;
  334.   double supertime;
  335.  
  336.   printf("\n");
  337.   printf("General Info: \n");
  338.   printf("Width: %d\nHeight: %d\n", curVidStream->mb_width * 16, curVidStream->mb_height * 16);
  339.  
  340.   for (i = 1; i < 4; i++) {
  341.  
  342.     if (stat_a[i].number == 0)
  343.       continue;
  344.  
  345.     switch (i) {
  346.     case 1:
  347.       printf("I FRAMES\n");
  348.       break;
  349.     case 2:
  350.       printf("P FRAMES\n");
  351.       break;
  352.     case 3:
  353.       printf("B FRAMES\n");
  354.       break;
  355.     }
  356.  
  357.     printf("Number: %d\n", stat_a[i].number);
  358.     printf("Avg. Size: %d bytes + %d bits\n",
  359.        stat_a[i].totsize / (8 * stat_a[i].number), (stat_a[i].totsize / stat_a[i].number) % 8);
  360.     if (stat_a[i].i_mbnum > 0) {
  361.       printf("\tI Macro Block Stats:\n");
  362.       printf("\t%d I Macroblocks\n", stat_a[i].i_mbnum);
  363.       printf("\tAvg. Size: %d bytes + %d bits\n",
  364.          stat_a[i].i_mbsize / (8 * stat_a[i].i_mbnum),
  365.          (stat_a[i].i_mbsize / stat_a[i].i_mbnum) % 8);
  366.       printf("\t\tCoded Block Pattern Histogram:\n");
  367.       for (j = 0; j < 64; j += 8) {
  368.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcbp[j],
  369.            stat_a[i].i_mbcbp[j + 1], stat_a[i].i_mbcbp[j + 2], stat_a[i].i_mbcbp[j + 3],
  370.            stat_a[i].i_mbcbp[j + 4], stat_a[i].i_mbcbp[j + 5], stat_a[i].i_mbcbp[j + 6],
  371.            stat_a[i].i_mbcbp[j + 7]);
  372.       }
  373.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  374.       for (j = 0; j < 64; j += 8) {
  375.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcoeff[j],
  376.            stat_a[i].i_mbcoeff[j + 1], stat_a[i].i_mbcoeff[j + 2],
  377.            stat_a[i].i_mbcoeff[j + 3], stat_a[i].i_mbcoeff[j + 4],
  378.            stat_a[i].i_mbcoeff[j + 5], stat_a[i].i_mbcoeff[j + 6],
  379.            stat_a[i].i_mbcoeff[j + 7]);
  380.       }
  381.     }
  382.     if (stat_a[i].p_mbnum > 0) {
  383.       printf("\tP Macro Block Stats:\n");
  384.       printf("\t%d P Macroblocks\n", stat_a[i].p_mbnum);
  385.       printf("\tAvg. Size: %d bytes + %d bits\n",
  386.          stat_a[i].p_mbsize / (8 * stat_a[i].p_mbnum),
  387.          (stat_a[i].p_mbsize / stat_a[i].p_mbnum) % 8);
  388.       printf("\t\tCoded Block Pattern Histogram:\n");
  389.       for (j = 0; j < 64; j += 8) {
  390.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcbp[j],
  391.            stat_a[i].p_mbcbp[j + 1], stat_a[i].p_mbcbp[j + 2], stat_a[i].p_mbcbp[j + 3],
  392.            stat_a[i].p_mbcbp[j + 4], stat_a[i].p_mbcbp[j + 5], stat_a[i].p_mbcbp[j + 6],
  393.            stat_a[i].p_mbcbp[j + 7]);
  394.       }
  395.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  396.       for (j = 0; j < 64; j += 8) {
  397.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcoeff[j],
  398.            stat_a[i].p_mbcoeff[j + 1], stat_a[i].p_mbcoeff[j + 2],
  399.            stat_a[i].p_mbcoeff[j + 3], stat_a[i].p_mbcoeff[j + 4],
  400.            stat_a[i].p_mbcoeff[j + 5], stat_a[i].p_mbcoeff[j + 6],
  401.            stat_a[i].p_mbcoeff[j + 7]);
  402.       }
  403.     }
  404.     if (stat_a[i].b_mbnum > 0) {
  405.       printf("\tB Macro Block Stats:\n");
  406.       printf("\t%d B Macroblocks\n", stat_a[i].b_mbnum);
  407.       printf("\tAvg. Size: %d bytes + %d bits\n",
  408.          stat_a[i].b_mbsize / (8 * stat_a[i].b_mbnum),
  409.          (stat_a[i].b_mbsize * stat_a[i].b_mbnum) % 8);
  410.       printf("\t\tCoded Block Pattern Histogram:\n");
  411.       for (j = 0; j < 64; j += 8) {
  412.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcbp[j],
  413.            stat_a[i].b_mbcbp[j + 1], stat_a[i].b_mbcbp[j + 2], stat_a[i].b_mbcbp[j + 3],
  414.            stat_a[i].b_mbcbp[j + 4], stat_a[i].b_mbcbp[j + 5], stat_a[i].b_mbcbp[j + 6],
  415.            stat_a[i].b_mbcbp[j + 7]);
  416.       }
  417.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  418.       for (j = 0; j < 64; j += 8) {
  419.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcoeff[j],
  420.            stat_a[i].b_mbcoeff[j + 1], stat_a[i].b_mbcoeff[j + 2],
  421.            stat_a[i].b_mbcoeff[j + 3], stat_a[i].b_mbcoeff[j + 4],
  422.            stat_a[i].b_mbcoeff[j + 5], stat_a[i].b_mbcoeff[j + 6],
  423.            stat_a[i].b_mbcoeff[j + 7]);
  424.       }
  425.     }
  426.     if (stat_a[i].bi_mbnum > 0) {
  427.       printf("\tBi Macro Block Stats:\n");
  428.       printf("\t%d Bi Macroblocks\n", stat_a[i].bi_mbnum);
  429.       printf("\tAvg. Size: %d bytes + %d bits\n",
  430.          stat_a[i].bi_mbsize / (8 * stat_a[i].bi_mbnum),
  431.          (stat_a[i].bi_mbsize * stat_a[i].bi_mbnum) % 8);
  432.       printf("\t\tCoded Block Pattern Histogram:\n");
  433.       for (j = 0; j < 64; j += 8) {
  434.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcbp[j],
  435.            stat_a[i].bi_mbcbp[j + 1], stat_a[i].bi_mbcbp[j + 2], stat_a[i].bi_mbcbp[j + 3],
  436.            stat_a[i].bi_mbcbp[j + 4], stat_a[i].bi_mbcbp[j + 5], stat_a[i].bi_mbcbp[j + 6],
  437.            stat_a[i].bi_mbcbp[j + 7]);
  438.       }
  439.       printf("\n\t\tNumber of Coefficients/Block Histogram:\n");
  440.       for (j = 0; j < 64; j += 8) {
  441.     printf("\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcoeff[j],
  442.            stat_a[i].bi_mbcoeff[j + 1], stat_a[i].bi_mbcoeff[j + 2],
  443.            stat_a[i].bi_mbcoeff[j + 3], stat_a[i].bi_mbcoeff[j + 4],
  444.            stat_a[i].bi_mbcoeff[j + 5], stat_a[i].bi_mbcoeff[j + 6],
  445.            stat_a[i].bi_mbcoeff[j + 7]);
  446.       }
  447.     }
  448.     printf("\nAvg. Time to Decode: %f secs.\n",
  449.        (stat_a[i].tottime / ((double) stat_a[i].number)));
  450.     printf("\n");
  451.     printf("*************************\n\n");
  452.   }
  453.  
  454.   supertot = stat_a[1].totsize + stat_a[2].totsize + stat_a[3].totsize;
  455.   supernum = stat_a[1].number + stat_a[2].number + stat_a[3].number;
  456.   supertime = stat_a[1].tottime + stat_a[2].tottime + stat_a[3].tottime;
  457.  
  458.   printf("Total Number of Frames: %d\n", supernum);
  459.   printf("Avg Frame Size: %d bytes %d bits\n",
  460.      supertot / (8 * supernum), (supertot / supernum) % 8);
  461.   printf("Total Time Decoding: %g secs.\n", supertime);
  462.   printf("Avg Decoding Time/Frame: %g secs.\n", supertime / ((double) supernum));
  463.   printf("Avg Decoding Frames/Sec: %g secs.\n", ((double) supernum) / supertime);
  464.   printf("\n");
  465.  
  466.   printf("Cache Hits/Miss\n");
  467.   for (i = 0; i < 8; i++) {
  468.     printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n",
  469.        cacheHit[i][0], cacheMiss[i][0], cacheHit[i][1], cacheMiss[i][1],
  470.        cacheHit[i][2], cacheMiss[i][2], cacheHit[i][3], cacheMiss[i][3]);
  471.     printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n",
  472.        cacheHit[i][4], cacheMiss[i][4], cacheHit[i][5], cacheMiss[i][5],
  473.        cacheHit[i][6], cacheMiss[i][6], cacheHit[i][7], cacheMiss[i][7]);
  474.   }
  475.  
  476. }
  477.  
  478. static void
  479. CollectStats()
  480. {
  481.   int i, j;
  482.  
  483.   i = stat_a[0].frametype;
  484.  
  485.   stat_a[i].totsize += stat_a[0].totsize;
  486.   stat_a[i].number += stat_a[0].number;
  487.   stat_a[i].i_mbsize += stat_a[0].i_mbsize;
  488.   stat_a[i].p_mbsize += stat_a[0].p_mbsize;
  489.   stat_a[i].b_mbsize += stat_a[0].b_mbsize;
  490.   stat_a[i].bi_mbsize += stat_a[0].bi_mbsize;
  491.   stat_a[i].i_mbnum += stat_a[0].i_mbnum;
  492.   stat_a[i].p_mbnum += stat_a[0].p_mbnum;
  493.   stat_a[i].b_mbnum += stat_a[0].b_mbnum;
  494.   stat_a[i].bi_mbnum += stat_a[0].bi_mbnum;
  495.  
  496.   for (j = 0; j < 64; j++) {
  497.  
  498.     stat_a[i].i_mbcbp[j] += stat_a[0].i_mbcbp[j];
  499.     stat_a[i].p_mbcbp[j] += stat_a[0].p_mbcbp[j];
  500.     stat_a[i].b_mbcbp[j] += stat_a[0].b_mbcbp[j];
  501.     stat_a[i].bi_mbcbp[j] += stat_a[0].bi_mbcbp[j];
  502.     stat_a[i].i_mbcoeff[j] += stat_a[0].i_mbcoeff[j];
  503.     stat_a[i].p_mbcoeff[j] += stat_a[0].p_mbcoeff[j];
  504.     stat_a[i].b_mbcoeff[j] += stat_a[0].b_mbcoeff[j];
  505.     stat_a[i].bi_mbcoeff[j] += stat_a[0].bi_mbcoeff[j];
  506.   }
  507.  
  508.   stat_a[i].tottime += stat_a[0].tottime;
  509.  
  510.   init_stat_struct(&(stat_a[0]));
  511. }
  512.  
  513. static unsigned int
  514. bitCountRead()
  515. {
  516.   return bitCount;
  517. }
  518.  
  519. static void
  520. StartTime()
  521. {
  522.   stat_a[0].tottime = ReadSysClock();
  523. }
  524.  
  525. static void
  526. EndTime()
  527. {
  528.   stat_a[0].tottime = ReadSysClock() - stat_a[0].tottime;
  529. }
  530. #endif
  531.  
  532. double realTimeStart;
  533. int totNumFrames = 0;
  534.  
  535. double
  536. ReadSysClock()
  537. {
  538.   struct timeval tv;
  539.   (void) gettimeofday(&tv, (struct timezone *)NULL);
  540.   return (tv.tv_sec + tv.tv_usec / 1000000.0);
  541. }
  542.  
  543. void
  544. PrintTimeInfo()
  545. {
  546.   double spent;
  547.  
  548.   spent = ReadSysClock() - realTimeStart;
  549.  
  550.   if (!quietFlag) {
  551.     printf("\nReal Time Spent (After Initializations): %f secs.\n", spent);
  552.     printf("Avg. Frames/Sec: %f\n", ((double) totNumFrames) / spent);
  553.   }
  554. }
  555.  
  556.  
  557.  
  558. /*
  559.  *--------------------------------------------------------------
  560.  *
  561.  * NewVidStream --
  562.  *
  563.  *    Allocates and initializes a VidStream structure. Takes
  564.  *      as parameter requested size for buffer length.
  565.  *
  566.  * Results:
  567.  *    A pointer to the new VidStream structure.
  568.  *
  569.  * Side effects:
  570.  *      None.
  571.  *
  572.  *--------------------------------------------------------------
  573.  */
  574.  
  575. VidStream *
  576. NewVidStream(bufLength)
  577.   int bufLength;
  578. {
  579.   int i, j;
  580.   VidStream *new;
  581.   static unsigned char default_intra_matrix[64] = {
  582.     8, 16, 19, 22, 26, 27, 29, 34,
  583.     16, 16, 22, 24, 27, 29, 34, 37,
  584.     19, 22, 26, 27, 29, 34, 34, 38,
  585.     22, 22, 26, 27, 29, 34, 37, 40,
  586.     22, 26, 27, 29, 32, 35, 40, 48,
  587.     26, 27, 29, 32, 35, 40, 48, 58,
  588.     26, 27, 29, 34, 38, 46, 56, 69,
  589.   27, 29, 35, 38, 46, 56, 69, 83};
  590.  
  591.   /* Check for legal buffer length. */
  592.  
  593.   if (bufLength < 4)
  594.     return NULL;
  595.  
  596.   /* Make buffer length multiple of 4. */
  597.  
  598.   bufLength = (bufLength + 3) >> 2;
  599.  
  600.   /* Allocate memory for new structure. */
  601.  
  602.   new = (VidStream *) malloc(sizeof(VidStream));
  603.  
  604.   /* Initialize pointers to extension and user data. */
  605.  
  606.   new->group.ext_data = new->group.user_data =
  607.     new->picture.extra_info = new->picture.user_data =
  608.     new->picture.ext_data = new->slice.extra_info =
  609.     new->ext_data = new->user_data = NULL;
  610.  
  611.   /* Copy default intra matrix. */
  612.  
  613.   for (i = 0; i < 8; i++) {
  614.     for (j = 0; j < 8; j++) {
  615.       new->intra_quant_matrix[j][i] = default_intra_matrix[i * 8 + j];
  616.     }
  617.   }
  618.  
  619.   /* Initialize crop table. */
  620.  
  621.   for (i = (-MAX_NEG_CROP); i < NUM_CROP_ENTRIES - MAX_NEG_CROP; i++) {
  622.     if (i <= 0) {
  623.       cropTbl[i + MAX_NEG_CROP] = 0;
  624.     } else if (i >= 255) {
  625.       cropTbl[i + MAX_NEG_CROP] = 255;
  626.     } else {
  627.       cropTbl[i + MAX_NEG_CROP] = i;
  628.     }
  629.   }
  630.  
  631.   /* Initialize non intra quantization matrix. */
  632.  
  633.   for (i = 0; i < 8; i++) {
  634.     for (j = 0; j < 8; j++) {
  635.       new->non_intra_quant_matrix[j][i] = 16;
  636.     }
  637.   }
  638.  
  639.   /* Initialize pointers to image spaces. */
  640.  
  641.   new->current = new->past = new->future = NULL;
  642.   for (i = 0; i < RING_BUF_SIZE; i++) {
  643.     new->ring[i] = NULL;
  644.   }
  645.  
  646.   /* Create buffer. */
  647.  
  648.   new->buf_start = (unsigned int *) malloc(bufLength * 4);
  649.  
  650.   /*
  651.    * Set max_buf_length to one less than actual length to deal with messy
  652.    * data without proper seq. end codes.
  653.    */
  654.  
  655.   new->max_buf_length = bufLength - 1;
  656.  
  657.   /* Initialize bitstream i/o fields. */
  658.  
  659.   new->bit_offset = 0;
  660.   new->buf_length = 0;
  661.   new->buffer = new->buf_start;
  662.  
  663.  
  664.   /* Return structure. */
  665.  
  666.   return new;
  667. }
  668.  
  669.  
  670.  
  671. /*
  672.  *--------------------------------------------------------------
  673.  *
  674.  * DestroyVidStream --
  675.  *
  676.  *    Deallocates a VidStream structure.
  677.  *
  678.  * Results:
  679.  *      None.
  680.  *
  681.  * Side effects:
  682.  *    None.
  683.  *
  684.  *--------------------------------------------------------------
  685.  */
  686. void
  687. DestroyVidStream(astream)
  688.   VidStream *astream;
  689. {
  690.   int i;
  691.  
  692.   if (astream->ext_data != NULL)
  693.     free(astream->ext_data);
  694.  
  695.   if (astream->user_data != NULL)
  696.     free(astream->user_data);
  697.  
  698.   if (astream->group.ext_data != NULL)
  699.     free(astream->group.ext_data);
  700.  
  701.   if (astream->group.user_data != NULL)
  702.     free(astream->group.user_data);
  703.  
  704.   if (astream->picture.extra_info != NULL)
  705.     free(astream->picture.extra_info);
  706.  
  707.   if (astream->picture.ext_data != NULL)
  708.     free(astream->picture.ext_data);
  709.  
  710.   if (astream->picture.user_data != NULL)
  711.     free(astream->picture.user_data);
  712.  
  713.   if (astream->slice.extra_info != NULL)
  714.     free(astream->slice.extra_info);
  715.  
  716.   if (astream->buf_start != NULL)
  717.     free(astream->buf_start);
  718.  
  719.   for (i = 0; i < RING_BUF_SIZE; i++) {
  720.     if (astream->ring[i] != NULL) {
  721.       DestroyPictImage(astream->ring[i]);
  722.       astream->ring[i] = NULL;
  723.     }
  724.   }
  725.  
  726.   free((char *) astream);
  727. }
  728.  
  729.  
  730.  
  731.  
  732. /*
  733.  *--------------------------------------------------------------
  734.  *
  735.  * NewPictImage --
  736.  *
  737.  *    Allocates and initializes a PictImage structure.
  738.  *      The width and height of the image space are passed in
  739.  *      as parameters.
  740.  *
  741.  * Results:
  742.  *    A pointer to the new PictImage structure.
  743.  *
  744.  * Side effects:
  745.  *    None.
  746.  *
  747.  *--------------------------------------------------------------
  748.  */
  749.  
  750. PictImage *
  751. NewPictImage(width, height)
  752.   unsigned int width, height;
  753. {
  754.   PictImage *new;
  755.  
  756.   /* Allocate memory space for new structure. */
  757.  
  758.   new = (PictImage *) malloc(sizeof(PictImage));
  759.  
  760.  
  761.   /* Allocate memory for image spaces. */
  762.  
  763. #ifdef SH_MEM
  764.   new->ximage = NULL;
  765.  
  766.   if (shmemFlag) {
  767.     Visual *fc_visual;
  768.     int depth;
  769.     Visual *FindFullColorVisual();
  770.  
  771.     if (ditherType == Twox2_DITHER) {
  772.       new->ximage = XShmCreateImage(display, None, 8, ZPixmap, NULL,
  773.                     &(new->shminfo), width * 2, height * 2);
  774.     } else if (ditherType == FULL_COLOR_DITHER) {
  775.       fc_visual = FindFullColorVisual(display, &depth);
  776.       new->ximage = XShmCreateImage(display, fc_visual, depth, ZPixmap,
  777.                     NULL, &(new->shminfo), width, height);
  778.     } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
  779.       new->ximage = XShmCreateImage(display, None, 1, XYBitmap,
  780.                     NULL, &(new->shminfo), width, height);
  781.     } else {
  782.       new->ximage = XShmCreateImage(display, None, 8, ZPixmap, NULL,
  783.                     &(new->shminfo), width, height);
  784.     }
  785.  
  786.     /* If no go, then revert to normal Xlib calls. */
  787.  
  788.     if (new->ximage == NULL) {
  789.       shmemFlag = 0;
  790.       if (!quietFlag) {
  791.     fprintf(stderr, "Shared memory error, disabling.\n");
  792.     fprintf(stderr, "Ximage error.\n");
  793.       }
  794.       goto shmemerror;
  795.     }
  796.     /* Success here, continue. */
  797.  
  798.     new->shminfo.shmid = shmget(IPC_PRIVATE, (new->ximage->bytes_per_line *
  799.                           new->ximage->height),
  800.                 IPC_CREAT | 0777);
  801.  
  802.     if (new->shminfo.shmid < 0) {
  803.       XDestroyImage(new->ximage);
  804.       new->ximage = NULL;
  805.       shmemFlag = 0;
  806.       if (!quietFlag) {
  807.     fprintf(stderr, "Shared memory error, disabling.\n");
  808.     fprintf(stderr, "Seg. id. error.\n");
  809.       }
  810.       goto shmemerror;
  811.     }
  812.     new->shminfo.shmaddr = (char *) shmat(new->shminfo.shmid, 0, 0);
  813.     if (new->shminfo.shmaddr == ((char *) -1)) {
  814.       XDestroyImage(new->ximage);
  815.       new->ximage = NULL;
  816.       shmemFlag = 0;
  817.       if (!quietFlag) {
  818.     fprintf(stderr, "Shared memory error, disabling.\n");
  819.     fprintf(stderr, "Address error.\n");
  820.       }
  821.       goto shmemerror;
  822.     }
  823.     new->ximage->data = new->shminfo.shmaddr;
  824.     new->display = (unsigned char *) new->ximage->data;
  825.     new->shminfo.readOnly = False;
  826.  
  827.     XShmAttach(display, &(new->shminfo));
  828.     XSync(display, False);
  829.  
  830.     if (gXErrorFlag) {
  831.       /* Ultimate failure here. */
  832.       XDestroyImage(new->ximage);
  833.       new->ximage = NULL;
  834.       shmemFlag = 0;
  835.       if (!quietFlag) {
  836.     fprintf(stderr, "Shared memory error, disabling.\n");
  837.       }
  838.       gXErrorFlag = 0;
  839.       goto shmemerror;
  840.     } else {
  841.       shmctl(new->shminfo.shmid, IPC_RMID, 0);
  842.     }
  843.  
  844.     if (!quietFlag) {
  845.       fprintf(stderr, "Sharing memory.\n");
  846.     }
  847.   } else
  848. #endif
  849.   {
  850. shmemerror:
  851.  
  852.     if ((ditherType == Twox2_DITHER) || (ditherType == FULL_COLOR_DITHER)) {
  853.       new->display = (unsigned char *) malloc(width * height * 4);
  854.     } else {
  855.       new->display = (unsigned char *) malloc(width * height);
  856.     }
  857.   }
  858.  
  859.   new->luminance = (unsigned char *) malloc(width * height);
  860.   new->Cr = (unsigned char *) malloc(width * height / 4);
  861.   new->Cb = (unsigned char *) malloc(width * height / 4);
  862.  
  863.   /* Reset locked flag. */
  864.  
  865.   new->locked = 0;
  866.  
  867.   /* Return pointer to new structure. */
  868.  
  869.   return new;
  870. }
  871.  
  872.  
  873.  
  874. /*
  875.  *--------------------------------------------------------------
  876.  *
  877.  * DestroyPictImage --
  878.  *
  879.  *    Deallocates a PictImage structure.
  880.  *
  881.  * Results:
  882.  *      None.
  883.  *
  884.  * Side effects:
  885.  *    None.
  886.  *
  887.  *--------------------------------------------------------------
  888.  */
  889. void
  890. DestroyPictImage(apictimage)
  891.   PictImage *apictimage;
  892. {
  893.   if (apictimage->luminance != NULL) {
  894.     free(apictimage->luminance);
  895.   }
  896.   if (apictimage->Cr != NULL) {
  897.     free(apictimage->Cr);
  898.   }
  899.   if (apictimage->Cb != NULL) {
  900.     free(apictimage->Cb);
  901.   }
  902. #ifdef SH_MEM
  903.   if (apictimage->ximage != NULL) {
  904.     XShmDetach(display, &(apictimage->shminfo));
  905.     XDestroyImage(apictimage->ximage);
  906.     shmdt(apictimage->shminfo.shmaddr);
  907.     apictimage->ximage = NULL;
  908.     apictimage->display = NULL;
  909.   }
  910. #endif
  911.  
  912.   if (apictimage->display != NULL) {
  913.     free(apictimage->display);
  914.   }
  915.   free(apictimage);
  916. }
  917.  
  918.  
  919.  
  920. /*
  921.  *--------------------------------------------------------------
  922.  *
  923.  * mpegVidRsrc --
  924.  *
  925.  *      Parses bit stream until MB_QUANTUM number of
  926.  *      macroblocks have been decoded or current slice or
  927.  *      picture ends, whichever comes first. If the start
  928.  *      of a frame is encountered, the frame is time stamped
  929.  *      with the value passed in time_stamp. If the value
  930.  *      passed in buffer is not null, the video stream buffer
  931.  *      is set to buffer and the length of the buffer is
  932.  *      expected in value passed in through length. The current
  933.  *      video stream is set to vid_stream. If vid_stream
  934.  *      is passed as NULL, a new VidStream structure is created
  935.  *      and initialized and used as the current video stream.
  936.  *
  937.  * Results:
  938.  *      A pointer to the video stream structure used.
  939.  *
  940.  * Side effects:
  941.  *      Bit stream is irreversibly parsed. If a picture is completed,
  942.  *      a function is called to display the frame at the correct time.
  943.  *
  944.  *--------------------------------------------------------------
  945.  */
  946.  
  947. VidStream *
  948. mpegVidRsrc(time_stamp, vid_stream)
  949.   TimeStamp time_stamp;
  950.   VidStream *vid_stream;
  951. {
  952.   static int first = 1;
  953.   unsigned int data;
  954.   int i, status;
  955.  
  956.   /* If vid_stream is null, create new VidStream structure. */
  957.  
  958.   if (vid_stream == NULL) {
  959.     return NULL;
  960.   }
  961.   /*
  962.    * Set global curVidStream to vid_stream. Necessary because bit i/o use
  963.    * curVidStream and are not passed vid_stream. Also set global bitstream
  964.    * parameters.
  965.    */
  966.  
  967.   curVidStream = vid_stream;
  968.   bitOffset = curVidStream->bit_offset;
  969. #ifdef UTIL2
  970.   curBits = *curVidStream->buffer << bitOffset;
  971. #else
  972.   curBits = *curVidStream->buffer;
  973. #endif
  974.   bufLength = curVidStream->buf_length;
  975.   bitBuffer = curVidStream->buffer;
  976.  
  977.   /*
  978.    * If called for the first time, find start code, make sure it is a
  979.    * sequence start code.
  980.    */
  981.  
  982.   if (first) {
  983.     next_start_code();
  984.     show_bits32(data);
  985.     if (data != SEQ_START_CODE) {
  986.       fprintf(stderr, "This is not an MPEG stream.");
  987.       DestroyVidStream(curVidStream);
  988.       exit(1);
  989.     }
  990.     first = 0;
  991.   }
  992.   /* Get next 32 bits (size of start codes). */
  993.  
  994.   show_bits32(data);
  995.  
  996.   /*
  997.    * Process according to start code (or parse macroblock if not a start code
  998.    * at all.
  999.    */
  1000.  
  1001.   switch (data) {
  1002.  
  1003.   case SEQ_END_CODE:
  1004.  
  1005.     /* Display last frame. */
  1006.  
  1007.     if (vid_stream->future != NULL) {
  1008.       vid_stream->current = vid_stream->future;
  1009.       ExecuteDisplay(vid_stream);
  1010.     }
  1011.     
  1012.     /* Sequence done. Do the right thing. For right now, exit. */
  1013.  
  1014.     if (!quietFlag) {
  1015.       fprintf(stderr, "\nDone!\n");
  1016.     }
  1017.  
  1018. #ifdef ANALYSIS
  1019.     PrintAllStats();
  1020. #endif
  1021.     PrintTimeInfo();
  1022.  
  1023.     if (loopFlag)
  1024.       longjmp(env, 1);
  1025.  
  1026.     DestroyVidStream(curVidStream);
  1027.     exit(0);
  1028.     break;
  1029.  
  1030.   case SEQ_START_CODE:
  1031.  
  1032.     /* Sequence start code. Parse sequence header. */
  1033.  
  1034.     if (ParseSeqHead(vid_stream) != PARSE_OK)
  1035.       goto error;
  1036.  
  1037.     /*
  1038.      * Return after sequence start code so that application above can use
  1039.      * info in header.
  1040.      */
  1041.  
  1042.     goto done;
  1043.  
  1044.   case GOP_START_CODE:
  1045.  
  1046.     /* Group of Pictures start code. Parse gop header. */
  1047.  
  1048.     if (ParseGOP(vid_stream) != PARSE_OK)
  1049.       goto error;
  1050.  
  1051.  
  1052.   case PICTURE_START_CODE:
  1053.  
  1054.     /* Picture start code. Parse picture header and first slice header. */
  1055.  
  1056.     status = ParsePicture(vid_stream, time_stamp);
  1057.  
  1058.     if (status == SKIP_PICTURE) {
  1059.       next_start_code();
  1060.       fprintf(stderr, "Skipping picture...");
  1061.       while (!next_bits(32, PICTURE_START_CODE)) {
  1062.     if (next_bits(32, GOP_START_CODE))
  1063.       break;
  1064.     else if (next_bits(32, SEQ_END_CODE))
  1065.       break;
  1066.     flush_bits(24);
  1067.     next_start_code();
  1068.       }
  1069.       fprintf(stderr, "Done.\n");
  1070.       goto done;
  1071.     } else if (status != PARSE_OK)
  1072.       goto error;
  1073.  
  1074.  
  1075.     if (ParseSlice(vid_stream) != PARSE_OK)
  1076.       goto error;
  1077.     break;
  1078.  
  1079.   default:
  1080.  
  1081.     /* Check for slice start code. */
  1082.  
  1083.     if ((data >= SLICE_MIN_START_CODE) && (data <= SLICE_MAX_START_CODE)) {
  1084.  
  1085.       /* Slice start code. Parse slice header. */
  1086.  
  1087.       if (ParseSlice(vid_stream) != PARSE_OK)
  1088.     goto error;
  1089.     }
  1090.     break;
  1091.   }
  1092.  
  1093.   /* Parse next MB_QUANTUM macroblocks. */
  1094.  
  1095.   for (i = 0; i < MB_QUANTUM; i++) {
  1096.  
  1097.     /* Check to see if actually a startcode and not a macroblock. */
  1098.  
  1099.     if (!next_bits(23, 0x00000000)) {
  1100.  
  1101.       /* Not start code. Parse Macroblock. */
  1102.  
  1103.       if (ParseMacroBlock(vid_stream) != PARSE_OK)
  1104.     goto error;
  1105.  
  1106. #ifdef ANALYSIS
  1107.       if (showmb_flag) {
  1108.     DoDitherImage(vid_stream->current->luminance, vid_stream->current->Cr,
  1109.               vid_stream->current->Cb, vid_stream->current->display,
  1110.               vid_stream->mb_height * 16, vid_stream->mb_width * 16);
  1111.     ExecuteDisplay(vid_stream);
  1112.       }
  1113. #endif
  1114.  
  1115.     } else {
  1116.  
  1117.       /* Not macroblock, actually start code. Get start code. */
  1118.  
  1119.       next_start_code();
  1120.       show_bits32(data);
  1121.  
  1122.       /*
  1123.        * If start code is outside range of slice start codes, frame is
  1124.        * complete, display frame.
  1125.        */
  1126.  
  1127.       if ((data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE)) {
  1128.  
  1129. #ifdef ANALYSIS
  1130.     EndTime();
  1131.     stat_a[0].totsize += bitCountRead() - pictureSizeCount;
  1132.     if (showEachFlag) {
  1133.       PrintOneStat();
  1134.     };
  1135.  
  1136.     CollectStats();
  1137. #endif
  1138.  
  1139.     DoPictureDisplay(vid_stream);
  1140.       }
  1141.       break;
  1142.     }
  1143.   }
  1144.  
  1145.   /* Return pointer to video stream structure. */
  1146.  
  1147.   goto done;
  1148.  
  1149. error:
  1150.   fprintf(stderr, "Error!!!!\n");
  1151.   next_start_code();
  1152.   goto done;
  1153.  
  1154. done:
  1155.  
  1156.   /* Copy global bit i/o variables back into vid_stream. */
  1157.  
  1158.   vid_stream->buffer = bitBuffer;
  1159.   vid_stream->buf_length = bufLength;
  1160.   vid_stream->bit_offset = bitOffset;
  1161.  
  1162.   return vid_stream;
  1163.  
  1164. }
  1165.  
  1166.  
  1167.  
  1168. /*
  1169.  *--------------------------------------------------------------
  1170.  *
  1171.  * ParseSeqHead --
  1172.  *
  1173.  *      Assumes bit stream is at the begining of the sequence
  1174.  *      header start code. Parses off the sequence header.
  1175.  *
  1176.  * Results:
  1177.  *      Fills the vid_stream structure with values derived and
  1178.  *      decoded from the sequence header. Allocates the pict image
  1179.  *      structures based on the dimensions of the image space
  1180.  *      found in the sequence header.
  1181.  *
  1182.  * Side effects:
  1183.  *      Bit stream irreversibly parsed off.
  1184.  *
  1185.  *--------------------------------------------------------------
  1186.  */
  1187.  
  1188. static int
  1189. ParseSeqHead(vid_stream)
  1190.   VidStream *vid_stream;
  1191. {
  1192.  
  1193.   unsigned int data;
  1194.   int i;
  1195.  
  1196.   /* Flush off sequence start code. */
  1197.  
  1198.   flush_bits32;
  1199.  
  1200.   /* Get horizontal size of image space. */
  1201.  
  1202.   get_bits12(data);
  1203.   vid_stream->h_size = data;
  1204.  
  1205.   /* Get vertical size of image space. */
  1206.  
  1207.   get_bits12(data);
  1208.   vid_stream->v_size = data;
  1209.  
  1210.   /* Calculate macroblock width and height of image space. */
  1211.  
  1212.   vid_stream->mb_width = (vid_stream->h_size + 15) / 16;
  1213.   vid_stream->mb_height = (vid_stream->v_size + 15) / 16;
  1214.  
  1215.   /* If dither type is MBORDERED allocate ditherFlags. */
  1216.  
  1217.   if (ditherType == MBORDERED_DITHER) {
  1218.     ditherFlags = (char *) malloc(vid_stream->mb_width*vid_stream->mb_height);
  1219.   }
  1220.  
  1221.   /* Initialize lmaxx, lmaxy, cmaxx, cmaxy. */
  1222.  
  1223.   lmaxx = vid_stream->mb_width*16-1;
  1224.   lmaxy = vid_stream->mb_height*16-1;
  1225.   cmaxx = vid_stream->mb_width*8-1;
  1226.   cmaxy = vid_stream->mb_height*8-1;
  1227.  
  1228.   /*
  1229.    * Initialize ring buffer of pict images now that dimensions of image space
  1230.    * are known.
  1231.    */
  1232.  
  1233. #ifdef SH_MEM
  1234.   if (display != NULL) {
  1235.     InstallXErrorHandler();
  1236.   }
  1237. #endif
  1238.  
  1239.   if (vid_stream->ring[0] == NULL) {
  1240.     for (i = 0; i < RING_BUF_SIZE; i++) {
  1241.       vid_stream->ring[i] = NewPictImage(vid_stream->mb_width * 16,
  1242.                      vid_stream->mb_height * 16);
  1243.     }
  1244.   }
  1245. #ifdef SH_MEM
  1246.   if (display != NULL) {
  1247.     DeInstallXErrorHandler();
  1248.   }
  1249. #endif
  1250.  
  1251.   /* Parse of aspect ratio code. */
  1252.  
  1253.   get_bits4(data);
  1254.   vid_stream->aspect_ratio = (unsigned char) data;
  1255.  
  1256.   /* Parse off picture rate code. */
  1257.  
  1258.   get_bits4(data);
  1259.   vid_stream->picture_rate = (unsigned char) data;
  1260.  
  1261.   /* Parse off bit rate. */
  1262.  
  1263.   get_bits18(data);
  1264.   vid_stream->bit_rate = data;
  1265.  
  1266.   /* Flush marker bit. */
  1267.  
  1268.   flush_bits(1);
  1269.  
  1270.   /* Parse off vbv buffer size. */
  1271.  
  1272.   get_bits10(data);
  1273.   vid_stream->vbv_buffer_size = data;
  1274.  
  1275.   /* Parse off contrained parameter flag. */
  1276.  
  1277.   get_bits1(data);
  1278.   if (data) {
  1279.     vid_stream->const_param_flag = TRUE;
  1280.   } else
  1281.     vid_stream->const_param_flag = FALSE;
  1282.  
  1283.   /*
  1284.    * If intra_quant_matrix_flag set, parse off intra quant matrix values.
  1285.    */
  1286.  
  1287.   get_bits1(data);
  1288.   if (data) {
  1289.     for (i = 0; i < 64; i++) {
  1290.       get_bits8(data);
  1291.  
  1292.       vid_stream->intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  1293.     (unsigned char) data;
  1294.     }
  1295.   }
  1296.   /*
  1297.    * If non intra quant matrix flag set, parse off non intra quant matrix
  1298.    * values.
  1299.    */
  1300.  
  1301.   get_bits1(data);
  1302.   if (data) {
  1303.     for (i = 0; i < 64; i++) {
  1304.       get_bits8(data);
  1305.  
  1306.       vid_stream->non_intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  1307.     (unsigned char) data;
  1308.     }
  1309.   }
  1310.   /* Go to next start code. */
  1311.  
  1312.   next_start_code();
  1313.  
  1314.   /*
  1315.    * If next start code is extension start code, parse off extension data.
  1316.    */
  1317.  
  1318.   if (next_bits(32, EXT_START_CODE)) {
  1319.     flush_bits32;
  1320.     if (vid_stream->ext_data != NULL) {
  1321.       free(vid_stream->ext_data);
  1322.       vid_stream->ext_data = NULL;
  1323.     }
  1324.     vid_stream->ext_data = get_ext_data();
  1325.   }
  1326.   /* If next start code is user start code, parse off user data. */
  1327.  
  1328.   if (next_bits(32, USER_START_CODE)) {
  1329.     flush_bits32;
  1330.     if (vid_stream->user_data != NULL) {
  1331.       free(vid_stream->user_data);
  1332.       vid_stream->user_data = NULL;
  1333.     }
  1334.     vid_stream->user_data = get_ext_data();
  1335.   }
  1336.   return PARSE_OK;
  1337. }
  1338.  
  1339.  
  1340.  
  1341. /*
  1342.  *--------------------------------------------------------------
  1343.  *
  1344.  * ParseGOP --
  1345.  *
  1346.  *      Parses of group of pictures header from bit stream
  1347.  *      associated with vid_stream.
  1348.  *
  1349.  * Results:
  1350.  *      Values in gop header placed into video stream structure.
  1351.  *
  1352.  * Side effects:
  1353.  *      Bit stream irreversibly parsed.
  1354.  *
  1355.  *--------------------------------------------------------------
  1356.  */
  1357.  
  1358. static int
  1359. ParseGOP(vid_stream)
  1360.   VidStream *vid_stream;
  1361. {
  1362.   unsigned int data;
  1363.  
  1364.   /* Flush group of pictures start code. WWWWWWOOOOOOOSSSSSSHHHHH!!! */
  1365.  
  1366.   flush_bits32;
  1367.  
  1368.   /* Parse off drop frame flag. */
  1369.  
  1370.   get_bits1(data);
  1371.   if (data) {
  1372.     vid_stream->group.drop_flag = TRUE;
  1373.   } else
  1374.     vid_stream->group.drop_flag = FALSE;
  1375.  
  1376.   /* Parse off hour component of time code. */
  1377.  
  1378.   get_bits5(data);
  1379.   vid_stream->group.tc_hours = data;
  1380.  
  1381.   /* Parse off minute component of time code. */
  1382.  
  1383.   get_bits6(data);
  1384.   vid_stream->group.tc_minutes = data;
  1385.  
  1386.   /* Flush marker bit. */
  1387.  
  1388.   flush_bits(1);
  1389.  
  1390.   /* Parse off second component of time code. */
  1391.  
  1392.   get_bits6(data);
  1393.   vid_stream->group.tc_seconds = data;
  1394.  
  1395.   /* Parse off picture count component of time code. */
  1396.  
  1397.   get_bits6(data);
  1398.   vid_stream->group.tc_pictures = data;
  1399.  
  1400.   /* Parse off closed gop and broken link flags. */
  1401.  
  1402.   get_bits2(data);
  1403.   if (data > 1) {
  1404.     vid_stream->group.closed_gop = TRUE;
  1405.     if (data > 2) {
  1406.       vid_stream->group.broken_link = TRUE;
  1407.     } else
  1408.       vid_stream->group.broken_link = FALSE;
  1409.   } else {
  1410.     vid_stream->group.closed_gop = FALSE;
  1411.     if (data) {
  1412.       vid_stream->group.broken_link = TRUE;
  1413.     } else
  1414.       vid_stream->group.broken_link = FALSE;
  1415.   }
  1416.  
  1417.   /* Goto next start code. */
  1418.  
  1419.   next_start_code();
  1420.  
  1421.   /* If next start code is extension data, parse off extension data. */
  1422.  
  1423.   if (next_bits(32, EXT_START_CODE)) {
  1424.     flush_bits32;
  1425.     if (vid_stream->group.ext_data != NULL) {
  1426.       free(vid_stream->group.ext_data);
  1427.       vid_stream->group.ext_data = NULL;
  1428.     }
  1429.     vid_stream->group.ext_data = get_ext_data();
  1430.   }
  1431.   /* If next start code is user data, parse off user data. */
  1432.  
  1433.   if (next_bits(32, USER_START_CODE)) {
  1434.     flush_bits32;
  1435.     if (vid_stream->group.user_data != NULL) {
  1436.       free(vid_stream->group.user_data);
  1437.       vid_stream->group.user_data = NULL;
  1438.     }
  1439.     vid_stream->group.user_data = get_ext_data();
  1440.   }
  1441.   return PARSE_OK;
  1442. }
  1443.  
  1444.  
  1445.  
  1446. /*
  1447.  *--------------------------------------------------------------
  1448.  *
  1449.  * ParsePicture --
  1450.  *
  1451.  *      Parses picture header. Marks picture to be presented
  1452.  *      at particular time given a time stamp.
  1453.  *
  1454.  * Results:
  1455.  *      Values from picture header put into video stream structure.
  1456.  *
  1457.  * Side effects:
  1458.  *      Bit stream irreversibly parsed.
  1459.  *
  1460.  *--------------------------------------------------------------
  1461.  */
  1462.  
  1463. static int
  1464. ParsePicture(vid_stream, time_stamp)
  1465.   VidStream *vid_stream;
  1466.   TimeStamp time_stamp;
  1467. {
  1468.   unsigned int data;
  1469.   int i;
  1470.  
  1471.   /* Flush header start code. */
  1472.   flush_bits32;
  1473.  
  1474.   /* Parse off temporal reference. */
  1475.   get_bits10(data);
  1476.   vid_stream->picture.temp_ref = data;
  1477.  
  1478.   /* Parse of picture type. */
  1479.   get_bits3(data);
  1480.   vid_stream->picture.code_type = data;
  1481.  
  1482.   if ((vid_stream->picture.code_type == B_TYPE) &&
  1483.       (No_B_Flag ||
  1484.        (vid_stream->past == NULL) ||
  1485.        (vid_stream->future == NULL)))
  1486.     return SKIP_PICTURE;
  1487.  
  1488.   if ((vid_stream->picture.code_type == P_TYPE) &&
  1489.       (No_P_Flag || (vid_stream->future == NULL)))
  1490.     return SKIP_PICTURE;
  1491.  
  1492. #ifdef ANALYSIS
  1493.   StartTime();
  1494.   stat_a[0].frametype = vid_stream->picture.code_type;
  1495.   stat_a[0].number = 1;
  1496.   stat_a[0].totsize = 45;
  1497.   pictureSizeCount = bitCountRead();
  1498. #endif
  1499.  
  1500.   /* Parse off vbv buffer delay value. */
  1501.   get_bits16(data);
  1502.   vid_stream->picture.vbv_delay = data;
  1503.  
  1504.   /* If P or B type frame... */
  1505.  
  1506.   if ((vid_stream->picture.code_type == 2) || (vid_stream->picture.code_type == 3)) {
  1507.  
  1508.     /* Parse off forward vector full pixel flag. */
  1509.     get_bits1(data);
  1510.     if (data)
  1511.       vid_stream->picture.full_pel_forw_vector = TRUE;
  1512.     else
  1513.       vid_stream->picture.full_pel_forw_vector = FALSE;
  1514.  
  1515.     /* Parse of forw_r_code. */
  1516.     get_bits3(data);
  1517.  
  1518.     /* Decode forw_r_code into forw_r_size and forw_f. */
  1519.  
  1520.     vid_stream->picture.forw_r_size = data - 1;
  1521.     vid_stream->picture.forw_f = (1 << vid_stream->picture.forw_r_size);
  1522.   }
  1523.   /* If B type frame... */
  1524.  
  1525.   if (vid_stream->picture.code_type == 3) {
  1526.  
  1527.     /* Parse off back vector full pixel flag. */
  1528.     get_bits1(data);
  1529.     if (data)
  1530.       vid_stream->picture.full_pel_back_vector = TRUE;
  1531.     else
  1532.       vid_stream->picture.full_pel_back_vector = FALSE;
  1533.  
  1534.     /* Parse off back_r_code. */
  1535.     get_bits3(data);
  1536.  
  1537.     /* Decode back_r_code into back_r_size and back_f. */
  1538.  
  1539.     vid_stream->picture.back_r_size = data - 1;
  1540.     vid_stream->picture.back_f = (1 << vid_stream->picture.back_r_size);
  1541.   }
  1542.   /* Get extra bit picture info. */
  1543.  
  1544.   if (vid_stream->picture.extra_info != NULL) {
  1545.     free(vid_stream->picture.extra_info);
  1546.     vid_stream->picture.extra_info = NULL;
  1547.   }
  1548.   vid_stream->picture.extra_info = get_extra_bit_info();
  1549.  
  1550.   /* Goto next start code. */
  1551.   next_start_code();
  1552.  
  1553.   /* If start code is extension start code, parse off extension data. */
  1554.  
  1555.   if (next_bits(32, EXT_START_CODE)) {
  1556.     flush_bits32;
  1557.  
  1558.     if (vid_stream->picture.ext_data != NULL) {
  1559.       free(vid_stream->picture.ext_data);
  1560.       vid_stream->picture.ext_data = NULL;
  1561.     }
  1562.     vid_stream->picture.ext_data = get_ext_data();
  1563.   }
  1564.   /* If start code is user start code, parse off user data. */
  1565.  
  1566.   if (next_bits(32, USER_START_CODE)) {
  1567.     flush_bits32;
  1568.  
  1569.     if (vid_stream->picture.user_data != NULL) {
  1570.       free(vid_stream->picture.user_data);
  1571.       vid_stream->picture.user_data = NULL;
  1572.     }
  1573.     vid_stream->picture.user_data = get_ext_data();
  1574.   }
  1575.   /* Find a pict image structure in ring buffer not currently locked. */
  1576.  
  1577.   i = 0;
  1578.  
  1579.   while (vid_stream->ring[i]->locked != 0) {
  1580.     if (++i >= RING_BUF_SIZE) {
  1581.       perror("Fatal error. Ring buffer full.");
  1582.       exit(1);
  1583.     }
  1584.   }
  1585.  
  1586.   /* Set current pict image structure to the one just found in ring. */
  1587.  
  1588.   vid_stream->current = vid_stream->ring[i];
  1589.  
  1590.   /* Set time stamp. */
  1591.  
  1592.   vid_stream->current->show_time = time_stamp;
  1593.  
  1594.   /* Reset past macroblock address field. */
  1595.  
  1596.   vid_stream->mblock.past_mb_addr = -1;
  1597.  
  1598.   return PARSE_OK;
  1599. }
  1600.  
  1601.  
  1602.  
  1603. /*
  1604.  *--------------------------------------------------------------
  1605.  *
  1606.  * ParseSlice --
  1607.  *
  1608.  *      Parses off slice header.
  1609.  *
  1610.  * Results:
  1611.  *      Values found in slice header put into video stream structure.
  1612.  *
  1613.  * Side effects:
  1614.  *      Bit stream irreversibly parsed.
  1615.  *
  1616.  *--------------------------------------------------------------
  1617.  */
  1618.  
  1619. static int
  1620. ParseSlice(vid_stream)
  1621.   VidStream *vid_stream;
  1622. {
  1623.   unsigned int data;
  1624.  
  1625.   /* Flush slice start code. */
  1626.  
  1627.   flush_bits(24);
  1628.  
  1629.   /* Parse off slice vertical position. */
  1630.  
  1631.   get_bits8(data);
  1632.   vid_stream->slice.vert_pos = data;
  1633.  
  1634.   /* Parse off quantization scale. */
  1635.  
  1636.   get_bits5(data);
  1637.   vid_stream->slice.quant_scale = data;
  1638.  
  1639.   /* Parse off extra bit slice info. */
  1640.  
  1641.   if (vid_stream->slice.extra_info != NULL) {
  1642.     free(vid_stream->slice.extra_info);
  1643.     vid_stream->slice.extra_info = NULL;
  1644.   }
  1645.   vid_stream->slice.extra_info = get_extra_bit_info();
  1646.  
  1647.   /* Reset past intrablock address. */
  1648.  
  1649.   vid_stream->mblock.past_intra_addr = -2;
  1650.  
  1651.   /* Reset previous recon motion vectors. */
  1652.  
  1653.   vid_stream->mblock.recon_right_for_prev = 0;
  1654.   vid_stream->mblock.recon_down_for_prev = 0;
  1655.   vid_stream->mblock.recon_right_back_prev = 0;
  1656.   vid_stream->mblock.recon_down_back_prev = 0;
  1657.  
  1658.   /* Reset macroblock address. */
  1659.  
  1660.   vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos - 1) *
  1661.                    vid_stream->mb_width) - 1;
  1662.  
  1663.   /* Reset past dct dc y, cr, and cb values. */
  1664.  
  1665.   vid_stream->block.dct_dc_y_past = 1024;
  1666.   vid_stream->block.dct_dc_cr_past = 1024;
  1667.   vid_stream->block.dct_dc_cb_past = 1024;
  1668.  
  1669.   return PARSE_OK;
  1670. }
  1671.  
  1672.  
  1673.  
  1674. /*
  1675.  *--------------------------------------------------------------
  1676.  *
  1677.  * ParseMacroBlock --
  1678.  *
  1679.  *      Parseoff macroblock. Reconstructs DCT values. Applies
  1680.  *      inverse DCT, reconstructs motion vectors, calculates and
  1681.  *      set pixel values for macroblock in current pict image
  1682.  *      structure.
  1683.  *
  1684.  * Results:
  1685.  *      Here's where everything really happens. Welcome to the
  1686.  *      heart of darkness.
  1687.  *
  1688.  * Side effects:
  1689.  *      Bit stream irreversibly parsed off.
  1690.  *
  1691.  *--------------------------------------------------------------
  1692.  */
  1693.  
  1694. static int
  1695. ParseMacroBlock(vid_stream)
  1696.   VidStream *vid_stream;
  1697. {
  1698.   int addr_incr;
  1699.   unsigned int data;
  1700.   int mask, i, recon_right_for, recon_down_for, recon_right_back,
  1701.       recon_down_back;
  1702.   int zero_block_flag;
  1703.   BOOLEAN mb_quant, mb_motion_forw, mb_motion_back, mb_pattern;
  1704.   int no_dith_flag = 0;
  1705.  
  1706. #ifdef ANALYSIS
  1707.   mbSizeCount = bitCountRead();
  1708. #endif
  1709.  
  1710.   /*
  1711.    * Parse off macroblock address increment and add to macroblock address.
  1712.    */
  1713.   do {
  1714.     DecodeMBAddrInc(addr_incr);
  1715.     if (addr_incr == MB_ESCAPE) {
  1716.       vid_stream->mblock.mb_address += 33;
  1717.       addr_incr = MB_STUFFING;
  1718.     }
  1719.   } while (addr_incr == MB_STUFFING);
  1720.   vid_stream->mblock.mb_address += addr_incr;
  1721.  
  1722.   if (vid_stream->mblock.mb_address > (vid_stream->mb_height *
  1723.                        vid_stream->mb_width - 1))
  1724.     return SKIP_TO_START_CODE;
  1725.  
  1726.   /*
  1727.    * If macroblocks have been skipped, process skipped macroblocks.
  1728.    */
  1729.  
  1730.   if (vid_stream->mblock.mb_address - vid_stream->mblock.past_mb_addr > 1) {
  1731.     if (vid_stream->picture.code_type == P_TYPE)
  1732.       ProcessSkippedPFrameMBlocks(vid_stream);
  1733.     else if (vid_stream->picture.code_type == B_TYPE)
  1734.       ProcessSkippedBFrameMBlocks(vid_stream);
  1735.   }
  1736.   /* Set past macroblock address to current macroblock address. */
  1737.   vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address;
  1738.  
  1739.   /* Based on picture type decode macroblock type. */
  1740.   switch (vid_stream->picture.code_type) {
  1741.   case I_TYPE:
  1742.     DecodeMBTypeI(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1743.           vid_stream->mblock.mb_intra);
  1744.     break;
  1745.  
  1746.   case P_TYPE:
  1747.     DecodeMBTypeP(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1748.           vid_stream->mblock.mb_intra);
  1749.     break;
  1750.  
  1751.   case B_TYPE:
  1752.     DecodeMBTypeB(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,
  1753.           vid_stream->mblock.mb_intra);
  1754.     break;
  1755.   }
  1756.  
  1757.   /* If quantization flag set, parse off new quantization scale. */
  1758.  
  1759.   if (mb_quant == TRUE) {
  1760.     get_bits5(data);
  1761.     vid_stream->slice.quant_scale = data;
  1762.   }
  1763.   /* If forward motion vectors exist... */
  1764.   if (mb_motion_forw == TRUE) {
  1765.  
  1766.     /* Parse off and decode horizontal forward motion vector. */
  1767.     DecodeMotionVectors(vid_stream->mblock.motion_h_forw_code);
  1768.  
  1769.     /* If horiz. forward r data exists, parse off. */
  1770.  
  1771.     if ((vid_stream->picture.forw_f != 1) &&
  1772.     (vid_stream->mblock.motion_h_forw_code != 0)) {
  1773.       get_bitsn(vid_stream->picture.forw_r_size, data);
  1774.       vid_stream->mblock.motion_h_forw_r = data;
  1775.     }
  1776.     /* Parse off and decode vertical forward motion vector. */
  1777.     DecodeMotionVectors(vid_stream->mblock.motion_v_forw_code);
  1778.  
  1779.     /* If vert. forw. r data exists, parse off. */
  1780.  
  1781.     if ((vid_stream->picture.forw_f != 1) &&
  1782.     (vid_stream->mblock.motion_v_forw_code != 0)) {
  1783.       get_bitsn(vid_stream->picture.forw_r_size, data);
  1784.       vid_stream->mblock.motion_v_forw_r = data;
  1785.     }
  1786.   }
  1787.   /* If back motion vectors exist... */
  1788.   if (mb_motion_back == TRUE) {
  1789.  
  1790.     /* Parse off and decode horiz. back motion vector. */
  1791.     DecodeMotionVectors(vid_stream->mblock.motion_h_back_code);
  1792.  
  1793.     /* If horiz. back r data exists, parse off. */
  1794.  
  1795.     if ((vid_stream->picture.back_f != 1) &&
  1796.     (vid_stream->mblock.motion_h_back_code != 0)) {
  1797.       get_bitsn(vid_stream->picture.back_r_size, data);
  1798.       vid_stream->mblock.motion_h_back_r = data;
  1799.     }
  1800.     /* Parse off and decode vert. back motion vector. */
  1801.     DecodeMotionVectors(vid_stream->mblock.motion_v_back_code);
  1802.  
  1803.     /* If vert. back r data exists, parse off. */
  1804.  
  1805.     if ((vid_stream->picture.back_f != 1) &&
  1806.     (vid_stream->mblock.motion_v_back_code != 0)) {
  1807.       get_bitsn(vid_stream->picture.back_r_size, data);
  1808.       vid_stream->mblock.motion_v_back_r = data;
  1809.     }
  1810.   }
  1811. #ifdef ANALYSIS
  1812.   if (vid_stream->mblock.mb_intra) {
  1813.     stat_a[0].i_mbnum++;
  1814.     mbCBPPtr = stat_a[0].i_mbcbp;
  1815.     mbCoeffPtr = stat_a[0].i_mbcoeff;
  1816.     mbSizePtr = &(stat_a[0].i_mbsize);
  1817.   } else if (mb_motion_back && mb_motion_forw) {
  1818.     stat_a[0].bi_mbnum++;
  1819.     mbCBPPtr = stat_a[0].bi_mbcbp;
  1820.     mbCoeffPtr = stat_a[0].bi_mbcoeff;
  1821.     mbSizePtr = &(stat_a[0].bi_mbsize);
  1822.   } else if (mb_motion_back) {
  1823.     stat_a[0].b_mbnum++;
  1824.     mbCBPPtr = stat_a[0].b_mbcbp;
  1825.     mbCoeffPtr = stat_a[0].b_mbcoeff;
  1826.     mbSizePtr = &(stat_a[0].b_mbsize);
  1827.   } else {
  1828.     stat_a[0].p_mbnum++;
  1829.     mbCBPPtr = stat_a[0].p_mbcbp;
  1830.     mbCoeffPtr = stat_a[0].p_mbcoeff;
  1831.     mbSizePtr = &(stat_a[0].p_mbsize);
  1832.   }
  1833. #endif
  1834.  
  1835.   /* If mblock pattern flag set, parse and decode CBP (code block pattern). */
  1836.   if (mb_pattern == TRUE) {
  1837.     DecodeCBP(vid_stream->mblock.cbp);
  1838.   }
  1839.   /* Otherwise, set CBP to zero. */
  1840.   else
  1841.     vid_stream->mblock.cbp = 0;
  1842.  
  1843.  
  1844. #ifdef ANALYSIS
  1845.   mbCBPPtr[vid_stream->mblock.cbp]++;
  1846. #endif
  1847.  
  1848.   /* Reconstruct motion vectors depending on picture type. */
  1849.   if (vid_stream->picture.code_type == P_TYPE) {
  1850.  
  1851.     /*
  1852.      * If no forw motion vectors, reset previous and current vectors to 0.
  1853.      */
  1854.  
  1855.     if (!mb_motion_forw) {
  1856.       recon_right_for = 0;
  1857.       recon_down_for = 0;
  1858.       vid_stream->mblock.recon_right_for_prev = 0;
  1859.       vid_stream->mblock.recon_down_for_prev = 0;
  1860.     }
  1861.     /*
  1862.      * Otherwise, compute new forw motion vectors. Reset previous vectors to
  1863.      * current vectors.
  1864.      */
  1865.  
  1866.     else {
  1867.       ComputeForwVector(&recon_right_for, &recon_down_for);
  1868.     }
  1869.   }
  1870.   if (vid_stream->picture.code_type == B_TYPE) {
  1871.  
  1872.     /* Reset prev. and current vectors to zero if mblock is intracoded. */
  1873.  
  1874.     if (vid_stream->mblock.mb_intra) {
  1875.       vid_stream->mblock.recon_right_for_prev = 0;
  1876.       vid_stream->mblock.recon_down_for_prev = 0;
  1877.       vid_stream->mblock.recon_right_back_prev = 0;
  1878.       vid_stream->mblock.recon_down_back_prev = 0;
  1879.     } else {
  1880.  
  1881.       /* If no forw vectors, current vectors equal prev. vectors. */
  1882.  
  1883.       if (!mb_motion_forw) {
  1884.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  1885.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  1886.       }
  1887.       /*
  1888.        * Otherwise compute forw. vectors. Reset prev vectors to new values.
  1889.        */
  1890.  
  1891.       else {
  1892.         ComputeForwVector(&recon_right_for, &recon_down_for);
  1893.       }
  1894.  
  1895.       /* If no back vectors, set back vectors to prev back vectors. */
  1896.  
  1897.       if (!mb_motion_back) {
  1898.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  1899.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  1900.       }
  1901.       /* Otherwise compute new vectors and reset prev. back vectors. */
  1902.  
  1903.       else {
  1904.     ComputeBackVector(&recon_right_back, &recon_down_back);
  1905.       }
  1906.  
  1907.       /*
  1908.        * Store vector existance flags in structure for possible skipped
  1909.        * macroblocks to follow.
  1910.        */
  1911.  
  1912.       vid_stream->mblock.bpict_past_forw = mb_motion_forw;
  1913.       vid_stream->mblock.bpict_past_back = mb_motion_back;
  1914.     }
  1915.   }
  1916.  
  1917.   /* For each possible block in macroblock. */
  1918.   if (ditherType == GRAY_DITHER ||
  1919.       ditherType == MONO_DITHER ||
  1920.       ditherType == MONO_THRESHOLD) {
  1921.     for (mask = 32, i = 0; i < 4; mask >>= 1, i++) {
  1922.  
  1923.       /* If block exists... */
  1924.       if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
  1925.     zero_block_flag = 0;
  1926.     ParseReconBlock(i);
  1927.       } else {
  1928.     zero_block_flag = 1;
  1929.       }
  1930.  
  1931.       /* If macroblock is intra coded... */
  1932.       if (vid_stream->mblock.mb_intra) {
  1933.     ReconIMBlock(vid_stream, i);
  1934.       } else if (mb_motion_forw && mb_motion_back) {
  1935.     ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1936.               recon_right_back, recon_down_back, zero_block_flag);
  1937.       } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1938.     ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1939.              zero_block_flag);
  1940.       } else if (mb_motion_back) {
  1941.     ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
  1942.              zero_block_flag);
  1943.       }
  1944.     }
  1945.     /* Kill the Chrominace blocks... */
  1946.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x2)) {
  1947.         ParseAwayBlock(4);
  1948.     }
  1949.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x1)) {
  1950.         ParseAwayBlock(5);
  1951.     }
  1952.   } else {
  1953.     if ((ditherType == MBORDERED_DITHER) &&
  1954.     (vid_stream->mblock.cbp == 0) &&
  1955.     (vid_stream->picture.code_type == 3) &&
  1956.     (!vid_stream->mblock.mb_intra) &&
  1957.     (!(mb_motion_forw && mb_motion_back))) {
  1958.       MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address, 
  1959.              mb_motion_forw, recon_right_for, recon_down_for, 
  1960.              mb_motion_back, recon_right_back, recon_down_back,
  1961.              vid_stream->past->display, vid_stream->future->display);
  1962.       ditherFlags[vid_stream->mblock.mb_address] = 0;
  1963.       no_dith_flag = 1;
  1964.     }
  1965.     else {
  1966.       for (mask = 32, i = 0; i < 6; mask >>= 1, i++) {
  1967.     
  1968.     /* If block exists... */
  1969.     if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {
  1970.       zero_block_flag = 0;
  1971.       ParseReconBlock(i);
  1972.     } else {
  1973.       zero_block_flag = 1;
  1974.     }
  1975.     
  1976.     /* If macroblock is intra coded... */
  1977.     if (vid_stream->mblock.mb_intra) {
  1978.       ReconIMBlock(vid_stream, i);
  1979.     } else if (mb_motion_forw && mb_motion_back) {
  1980.       ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1981.             recon_right_back, recon_down_back, zero_block_flag);
  1982.     } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1983.       ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,
  1984.                zero_block_flag);
  1985.     } else if (mb_motion_back) {
  1986.       ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,
  1987.                zero_block_flag);
  1988.     }
  1989.       }
  1990.     }
  1991.   }
  1992.  
  1993.   if ((ditherType == MBORDERED_DITHER) && (!no_dith_flag)) {
  1994.     if ((vid_stream->picture.code_type == 2) &&
  1995.     (vid_stream->mblock.cbp == 0) &&
  1996.     (!vid_stream->mblock.mb_intra)) {
  1997.       MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address,
  1998.                  1, recon_right_for, recon_down_for,
  1999.                  0, 0, 0,
  2000.                  vid_stream->future->display,
  2001.                  (unsigned char *) NULL);
  2002.       ditherFlags[vid_stream->mblock.mb_address] = 0;
  2003.     }
  2004.     else {
  2005.       ditherFlags[vid_stream->mblock.mb_address] = 1;
  2006.     }
  2007.   }
  2008.  
  2009.  
  2010.   /* If D Type picture, flush marker bit. */
  2011.   if (vid_stream->picture.code_type == 4)
  2012.     flush_bits(1);
  2013.  
  2014.   /* If macroblock was intracoded, set macroblock past intra address. */
  2015.   if (vid_stream->mblock.mb_intra)
  2016.     vid_stream->mblock.past_intra_addr =
  2017.       vid_stream->mblock.mb_address;
  2018.  
  2019. #ifdef ANALYSIS
  2020.   *mbSizePtr += bitCountRead() - mbSizeCount;
  2021. #endif
  2022.   return PARSE_OK;
  2023. }
  2024.  
  2025.  
  2026.  
  2027. /*
  2028.  *--------------------------------------------------------------
  2029.  *
  2030.  * ReconIMBlock --
  2031.  *
  2032.  *    Reconstructs intra coded macroblock.
  2033.  *
  2034.  * Results:
  2035.  *    None.
  2036.  *
  2037.  * Side effects:
  2038.  *    None.
  2039.  *
  2040.  *--------------------------------------------------------------
  2041.  */
  2042.  
  2043. static void
  2044. ReconIMBlock(vid_stream, bnum)
  2045.   VidStream *vid_stream;
  2046.   int bnum;
  2047. {
  2048.   int mb_row, mb_col, row, col, row_size, rr;
  2049.   unsigned char *dest;
  2050.  
  2051.   /* Calculate macroblock row and column from address. */
  2052.  
  2053.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2054.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2055.  
  2056.  
  2057.   /* If block is luminance block... */
  2058.  
  2059.   if (bnum < 4) {
  2060.  
  2061.     /* Calculate row and col values for upper left pixel of block. */
  2062.  
  2063.     row = mb_row * 16;
  2064.     col = mb_col * 16;
  2065.     if (bnum > 1)
  2066.       row += 8;
  2067.     if (bnum % 2)
  2068.       col += 8;
  2069.  
  2070.     /* Set dest to luminance plane of current pict image. */
  2071.  
  2072.     dest = vid_stream->current->luminance;
  2073.  
  2074.     /* Establish row size. */
  2075.  
  2076.     row_size = vid_stream->mb_width * 16;
  2077.   }
  2078.   /* Otherwise if block is Cr block... */
  2079.  
  2080.   else if (bnum == 4) {
  2081.  
  2082.     /* Set dest to Cr plane of current pict image. */
  2083.  
  2084.     dest = vid_stream->current->Cr;
  2085.  
  2086.     /* Establish row size. */
  2087.  
  2088.     row_size = vid_stream->mb_width * 8;
  2089.  
  2090.     /* Calculate row,col for upper left pixel of block. */
  2091.  
  2092.     row = mb_row * 8;
  2093.     col = mb_col * 8;
  2094.   }
  2095.   /* Otherwise block is Cb block, and ... */
  2096.  
  2097.   else {
  2098.  
  2099.     /* Set dest to Cb plane of current pict image. */
  2100.  
  2101.     dest = vid_stream->current->Cb;
  2102.  
  2103.     /* Establish row size. */
  2104.  
  2105.     row_size = vid_stream->mb_width * 8;
  2106.  
  2107.     /* Calculate row,col for upper left pixel value of block. */
  2108.  
  2109.     row = mb_row * 8;
  2110.     col = mb_col * 8;
  2111.   }
  2112.  
  2113.   /*
  2114.    * For each pixel in block, set to cropped reconstructed value from inverse
  2115.    * dct.
  2116.    */
  2117.   {
  2118.     short *sp = &vid_stream->block.dct_recon[0][0];
  2119.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2120.     dest += row * row_size + col;
  2121.     for (rr = 0; rr < 4; rr++, sp += 16, dest += row_size) {
  2122.       dest[0] = cm[sp[0]];
  2123.       assertCrop(sp[0]);
  2124.       dest[1] = cm[sp[1]];
  2125.       assertCrop(sp[1]);
  2126.       dest[2] = cm[sp[2]];
  2127.       assertCrop(sp[2]);
  2128.       dest[3] = cm[sp[3]];
  2129.       assertCrop(sp[3]);
  2130.       dest[4] = cm[sp[4]];
  2131.       assertCrop(sp[4]);
  2132.       dest[5] = cm[sp[5]];
  2133.       assertCrop(sp[5]);
  2134.       dest[6] = cm[sp[6]];
  2135.       assertCrop(sp[6]);
  2136.       dest[7] = cm[sp[7]];
  2137.       assertCrop(sp[7]);
  2138.  
  2139.       dest += row_size;
  2140.       dest[0] = cm[sp[8]];
  2141.       assertCrop(sp[8]);
  2142.       dest[1] = cm[sp[9]];
  2143.       assertCrop(sp[9]);
  2144.       dest[2] = cm[sp[10]];
  2145.       assertCrop(sp[10]);
  2146.       dest[3] = cm[sp[11]];
  2147.       assertCrop(sp[11]);
  2148.       dest[4] = cm[sp[12]];
  2149.       assertCrop(sp[12]);
  2150.       dest[5] = cm[sp[13]];
  2151.       assertCrop(sp[13]);
  2152.       dest[6] = cm[sp[14]];
  2153.       assertCrop(sp[14]);
  2154.       dest[7] = cm[sp[15]];
  2155.       assertCrop(sp[15]);
  2156.     }
  2157.   }
  2158. }
  2159.  
  2160.  
  2161.  
  2162. /*
  2163.  *--------------------------------------------------------------
  2164.  *
  2165.  * ReconPMBlock --
  2166.  *
  2167.  *    Reconstructs forward predicted macroblocks.
  2168.  *
  2169.  * Results:
  2170.  *      None.
  2171.  *
  2172.  * Side effects:
  2173.  *      None.
  2174.  *
  2175.  *--------------------------------------------------------------
  2176.  */
  2177.  
  2178. static void
  2179. ReconPMBlock(vid_stream, bnum, recon_right_for, recon_down_for, zflag)
  2180.   VidStream *vid_stream;
  2181.   int bnum, recon_right_for, recon_down_for, zflag;
  2182. {
  2183.   int mb_row, mb_col, row, col, row_size, rr;
  2184.   unsigned char *dest, *past;
  2185.   static int right_for, down_for, right_half_for, down_half_for;
  2186.   unsigned char *rindex1, *rindex2;
  2187.   unsigned char *index;
  2188.   short int *blockvals;
  2189.  
  2190. #ifdef LOOSE_MPEG
  2191.   int maxx, maxy;
  2192.   int illegalBlock = 0;
  2193.   int row_start, row_end, rfirst, rlast, col_start, col_end, cfirst, clast;
  2194. #endif
  2195.  
  2196.   /* Calculate macroblock row and column from address. */
  2197.  
  2198.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2199.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2200.  
  2201.   if (bnum < 4) {
  2202.  
  2203.     /* Calculate right_for, down_for motion vectors. */
  2204.  
  2205.     right_for = recon_right_for >> 1;
  2206.     down_for = recon_down_for >> 1;
  2207.     right_half_for = recon_right_for & 0x1;
  2208.     down_half_for = recon_down_for & 0x1;
  2209.  
  2210.     /* Set dest to luminance plane of current pict image. */
  2211.  
  2212.     dest = vid_stream->current->luminance;
  2213.  
  2214.     if (vid_stream->picture.code_type == B_TYPE) {
  2215.       if (vid_stream->past != NULL)
  2216.     past = vid_stream->past->luminance;
  2217.     } else {
  2218.  
  2219.       /* Set predicitive frame to current future frame. */
  2220.  
  2221.       if (vid_stream->future != NULL)
  2222.     past = vid_stream->future->luminance;
  2223.     }
  2224.  
  2225.     /* Establish row size. */
  2226.  
  2227.     row_size = vid_stream->mb_width << 4;
  2228.  
  2229.     /* Calculate row,col of upper left pixel in block. */
  2230.  
  2231.     row = mb_row << 4;
  2232.     col = mb_col << 4;
  2233.     if (bnum > 1)
  2234.       row += 8;
  2235.     if (bnum % 2)
  2236.       col += 8;
  2237.  
  2238. #ifdef LOOSE_MPEG
  2239.     /* Check for block illegality. */
  2240.  
  2241.     maxx = lmaxx; maxy = lmaxy;
  2242.  
  2243.     if (row + down_for + 7 > maxy) illegalBlock |= 0x4;
  2244.     else if (row + down_for < 0)  illegalBlock |= 0x1;
  2245.     
  2246.     if (col + right_for + 7 > maxx) illegalBlock |= 0x2;
  2247.     else if (col + right_for < 0) illegalBlock |= 0x8;
  2248.  
  2249. #endif
  2250.   }
  2251.   /* Otherwise, block is NOT luminance block, ... */
  2252.  
  2253.   else {
  2254.  
  2255.     /* Construct motion vectors. */
  2256.  
  2257.     recon_right_for /= 2;
  2258.     recon_down_for /= 2;
  2259.     right_for = recon_right_for >> 1;
  2260.     down_for = recon_down_for >> 1;
  2261.     right_half_for = recon_right_for & 0x1;
  2262.     down_half_for = recon_down_for & 0x1;
  2263.  
  2264.     /* Establish row size. */
  2265.  
  2266.     row_size = vid_stream->mb_width << 3;
  2267.  
  2268.     /* Calculate row,col of upper left pixel in block. */
  2269.  
  2270.     row = mb_row << 3;
  2271.     col = mb_col << 3;
  2272.  
  2273. #ifdef LOOSE_MPEG
  2274.     /* Check for block illegality. */
  2275.  
  2276.     maxx = cmaxx; maxy = cmaxy;
  2277.  
  2278.     if (row + down_for  + 7 > maxy) illegalBlock |= 0x4;
  2279.     else if (row + down_for < 0) illegalBlock |= 0x1;
  2280.  
  2281.     if (col + right_for  + 7 > maxx) illegalBlock  |= 0x2;
  2282.     else if (col + right_for < 0) illegalBlock |= 0x8;
  2283.  
  2284. #endif
  2285.  
  2286.     /* If block is Cr block... */
  2287.  
  2288.     if (bnum == 4) {
  2289.  
  2290.       /* Set dest to Cr plane of current pict image. */
  2291.  
  2292.       dest = vid_stream->current->Cr;
  2293.  
  2294.       if (vid_stream->picture.code_type == B_TYPE) {
  2295.  
  2296.     if (vid_stream->past != NULL)
  2297.       past = vid_stream->past->Cr;
  2298.       } else {
  2299.     if (vid_stream->future != NULL)
  2300.       past = vid_stream->future->Cr;
  2301.       }
  2302.     }
  2303.     /* Otherwise, block is Cb block... */
  2304.  
  2305.     else {
  2306.  
  2307.       /* Set dest to Cb plane of current pict image. */
  2308.  
  2309.       dest = vid_stream->current->Cb;
  2310.  
  2311.       if (vid_stream->picture.code_type == B_TYPE) {
  2312.     if (vid_stream->past != NULL)
  2313.       past = vid_stream->past->Cb;
  2314.       } else {
  2315.     if (vid_stream->future != NULL)
  2316.       past = vid_stream->future->Cb;
  2317.       }
  2318.     }
  2319.   }
  2320.  
  2321.   /* For each pixel in block... */
  2322.  
  2323. #ifdef LOOSE_MPEG
  2324.  
  2325.   if (illegalBlock) {
  2326.     if (illegalBlock & 0x1) {
  2327.       row_start = 0;
  2328.       row_end = row+down_for+8;
  2329.       rfirst = rlast = 8 - row_end;
  2330.     }
  2331.     else if (illegalBlock & 0x4) {
  2332.       row_start = row + down_for;
  2333.       row_end = maxy+1;
  2334.       rlast = row_end - row_start - 1;
  2335.       rfirst = 0;
  2336.     }
  2337.     else {
  2338.       row_start = row+down_for;
  2339.       row_end = row_start+8;
  2340.       rfirst = 0;
  2341.     }
  2342.  
  2343.     if (illegalBlock & 0x8) {
  2344.       col_start = 0;
  2345.       col_end = col + right_for + 8;
  2346.       cfirst = clast = 8 - col_end;
  2347.     }
  2348.     else if (illegalBlock & 0x2) {
  2349.       col_start = col + right_for;
  2350.       col_end = maxx + 1;
  2351.       clast = col_end - col_start - 1;
  2352.       cfirst = 0;
  2353.     }
  2354.     else {
  2355.       col_start = col + right_for;
  2356.       col_end = col_start + 8;
  2357.       cfirst = 0;
  2358.     }
  2359.  
  2360.     for (rr = row_start; rr < row_end; rr++) {
  2361.       rindex1 = past + (rr * row_size) + col_start;
  2362.       index = dest + ((row + rfirst) * row_size) + col + cfirst;
  2363.       for (cc = col_start; cc < col_end; cc++) {
  2364.     *index++ = *rindex1++;
  2365.       }
  2366.     }
  2367.  
  2368.     if (illegalBlock & 0x1) {
  2369.       for (rr = rlast -1; rr >=0; rr--) {
  2370.     index = dest + ((row + rr) * row_size) + col;
  2371.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2372.     for (cc = 0; cc < 8; cc ++) {
  2373.       *index++ = *rindex1++;
  2374.     }
  2375.       }
  2376.     }
  2377.     else if (illegalBlock & 0x4) {
  2378.       for (rr = rlast+1; rr < 8; rr++) {
  2379.     index = dest + ((row + rr) * row_size) + col;
  2380.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2381.     for (cc = 0; cc < 8; cc ++) {
  2382.       *index++ = *rindex1++;
  2383.     }
  2384.       }
  2385.     }
  2386.  
  2387.     if (illegalBlock & 0x2) {
  2388.       for (cc = clast+1; cc < 8; cc++) {
  2389.     index = dest + (row * row_size) + (col + cc);
  2390.     rindex1 = dest + (row * row_size) + (col + clast);
  2391.     for (rr = 0; rr < 8; rr++) {
  2392.       *index = *rindex1;
  2393.       index += row_size;
  2394.       rindex1 += row_size;
  2395.     }
  2396.       }
  2397.     }
  2398.     else if (illegalBlock & 0x8) {
  2399.       for (cc = clast-1; cc >= 0; cc--) {
  2400.     index = dest + (row * row_size) + (col + cc);
  2401.     rindex1 = dest + (row * row_size) + (col + clast);
  2402.     for (rr = 0; rr < 8; rr++) {
  2403.       *index = *rindex1;
  2404.       index += row_size;
  2405.       rindex1 += row_size;
  2406.     }
  2407.       }
  2408.     }
  2409.  
  2410.     if (!zflag) {
  2411.       for (rr = 0; rr < 8; rr++) {
  2412.     index = dest + (row*row_size) + col;
  2413.     blockvals = &(vid_stream->block.dct_recon[rr][0]);
  2414.     index[0] += blockvals[0];
  2415.     index[1] += blockvals[1];
  2416.     index[2] += blockvals[2];
  2417.     index[3] += blockvals[3];
  2418.     index[4] += blockvals[4];
  2419.     index[5] += blockvals[5];
  2420.     index[6] += blockvals[6];
  2421.     index[7] += blockvals[7];
  2422.       }
  2423.     }
  2424.   }
  2425.   else {
  2426.  
  2427. #endif
  2428.  
  2429.     index = dest + (row * row_size) + col;
  2430.     rindex1 = past + (row + down_for) * row_size + col + right_for;
  2431.     
  2432.     blockvals = &(vid_stream->block.dct_recon[0][0]);
  2433.     
  2434.     /*
  2435.      * Calculate predictive pixel value based on motion vectors and copy to
  2436.      * dest plane.
  2437.      */
  2438.     
  2439.     if ((!down_half_for) && (!right_half_for)) {
  2440.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2441.       if (!zflag)
  2442.     for (rr = 0; rr < 4; rr++) {
  2443.       index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
  2444.       index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
  2445.       index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
  2446.       index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
  2447.       index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
  2448.       index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
  2449.       index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
  2450.       index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
  2451.       index += row_size;
  2452.       rindex1 += row_size;
  2453.       
  2454.       index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
  2455.       index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
  2456.       index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
  2457.       index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
  2458.       index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
  2459.       index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
  2460.       index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
  2461.       index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
  2462.       blockvals += 16;
  2463.       index += row_size;
  2464.       rindex1 += row_size;
  2465.     }
  2466.       else {
  2467.     if (right_for & 0x1) {
  2468.       /* No alignment, use bye copy */
  2469.       for (rr = 0; rr < 4; rr++) {
  2470.         index[0] = rindex1[0];
  2471.         index[1] = rindex1[1];
  2472.         index[2] = rindex1[2];
  2473.         index[3] = rindex1[3];
  2474.         index[4] = rindex1[4];
  2475.         index[5] = rindex1[5];
  2476.         index[6] = rindex1[6];
  2477.         index[7] = rindex1[7];
  2478.         index += row_size;
  2479.         rindex1 += row_size;
  2480.         
  2481.         index[0] = rindex1[0];
  2482.         index[1] = rindex1[1];
  2483.         index[2] = rindex1[2];
  2484.         index[3] = rindex1[3];
  2485.         index[4] = rindex1[4];
  2486.         index[5] = rindex1[5];
  2487.         index[6] = rindex1[6];
  2488.         index[7] = rindex1[7];
  2489.         index += row_size;
  2490.         rindex1 += row_size;
  2491.       }
  2492.     } else if (right_for & 0x2) {
  2493.       /* Half-word bit aligned, use 16 bit copy */
  2494.       short *src = (short *)rindex1;
  2495.       short *dest = (short *)index;
  2496.       row_size >>= 1;
  2497.       for (rr = 0; rr < 4; rr++) {
  2498.         dest[0] = src[0];
  2499.         dest[1] = src[1];
  2500.         dest[2] = src[2];
  2501.         dest[3] = src[3];
  2502.         dest += row_size;
  2503.         src += row_size;
  2504.         
  2505.         dest[0] = src[0];
  2506.         dest[1] = src[1];
  2507.         dest[2] = src[2];
  2508.         dest[3] = src[3];
  2509.         dest += row_size;
  2510.         src += row_size;
  2511.       }
  2512.     } else {
  2513.       /* Word aligned, use 32 bit copy */
  2514.       int *src = (int *)rindex1;
  2515.       int *dest = (int *)index;
  2516.       row_size >>= 2;
  2517.       for (rr = 0; rr < 4; rr++) {
  2518.         dest[0] = src[0];
  2519.         dest[1] = src[1];
  2520.         dest += row_size;
  2521.         src += row_size;
  2522.         
  2523.         dest[0] = src[0];
  2524.         dest[1] = src[1];
  2525.         dest += row_size;
  2526.         src += row_size;
  2527.       }
  2528.     }
  2529.       }
  2530.     } else {
  2531.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2532.       rindex2 = rindex1 + right_half_for + (down_half_for * row_size);
  2533.       if (!zflag)
  2534.     for (rr = 0; rr < 4; rr++) {
  2535.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[0]];
  2536.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[1]];
  2537.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[2]];
  2538.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[3]];
  2539.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[4]];
  2540.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[5]];
  2541.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[6]];
  2542.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[7]];
  2543.       index += row_size;
  2544.       rindex1 += row_size;
  2545.       rindex2 += row_size;
  2546.       
  2547.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[8]];
  2548.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[9]];
  2549.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[10]];
  2550.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[11]];
  2551.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[12]];
  2552.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[13]];
  2553.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[14]];
  2554.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[15]];
  2555.       blockvals += 16;
  2556.       index += row_size;
  2557.       rindex1 += row_size;
  2558.       rindex2 += row_size;
  2559.     }
  2560.       else
  2561.     for (rr = 0; rr < 4; rr++) {
  2562.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2563.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2564.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2565.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2566.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2567.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2568.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2569.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2570.       index += row_size;
  2571.       rindex1 += row_size;
  2572.       rindex2 += row_size;
  2573.       
  2574.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2575.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2576.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2577.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2578.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2579.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2580.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2581.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2582.       index += row_size;
  2583.       rindex1 += row_size;
  2584.       rindex2 += row_size;
  2585.     }
  2586.     }
  2587.  
  2588. #ifdef LOOSE_MPEG
  2589.   }
  2590. #endif
  2591. }
  2592.  
  2593.  
  2594. /*
  2595.  *--------------------------------------------------------------
  2596.  *
  2597.  * ReconBMBlock --
  2598.  *
  2599.  *    Reconstructs back predicted macroblocks.
  2600.  *
  2601.  * Results:
  2602.  *      None.
  2603.  *
  2604.  * Side effects:
  2605.  *      None.
  2606.  *
  2607.  *--------------------------------------------------------------
  2608.  */
  2609.  
  2610. static void
  2611. ReconBMBlock(vid_stream, bnum, recon_right_back, recon_down_back, zflag)
  2612.   VidStream *vid_stream;
  2613.   int bnum, recon_right_back, recon_down_back, zflag;
  2614. {
  2615.   int mb_row, mb_col, row, col, row_size, rr;
  2616.   unsigned char *dest, *future;
  2617.   int right_back, down_back, right_half_back, down_half_back;
  2618.   unsigned char *rindex1, *rindex2;
  2619.   unsigned char *index;
  2620.   short int *blockvals;
  2621.  
  2622. #ifdef LOOSE_MPEG
  2623.   int illegalBlock = 0;
  2624.   int maxx, maxy;
  2625.   int row_start, row_end, rlast, rfirst, col_start, col_end, clast, cfirst;
  2626. #endif
  2627.  
  2628.   /* Calculate macroblock row and column from address. */
  2629.  
  2630.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2631.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2632.  
  2633.   /* If block is luminance block... */
  2634.  
  2635.   if (bnum < 4) {
  2636.  
  2637.     /* Calculate right_back, down_bakc motion vectors. */
  2638.  
  2639.     right_back = recon_right_back >> 1;
  2640.     down_back = recon_down_back >> 1;
  2641.     right_half_back = recon_right_back & 0x1;
  2642.     down_half_back = recon_down_back & 0x1;
  2643.  
  2644.     /* Set dest to luminance plane of current pict image. */
  2645.  
  2646.     dest = vid_stream->current->luminance;
  2647.  
  2648.     /*
  2649.      * If future frame exists, set future to luminance plane of future frame.
  2650.      */
  2651.  
  2652.     if (vid_stream->future != NULL)
  2653.       future = vid_stream->future->luminance;
  2654.  
  2655.     /* Establish row size. */
  2656.  
  2657.     row_size = vid_stream->mb_width << 4;
  2658.  
  2659.     /* Calculate row,col of upper left pixel in block. */
  2660.  
  2661.     row = mb_row << 4;
  2662.     col = mb_col << 4;
  2663.     if (bnum > 1)
  2664.       row += 8;
  2665.     if (bnum % 2)
  2666.       col += 8;
  2667.  
  2668. #ifdef LOOSE_MPEG
  2669.  
  2670.     /* Check for block illegality. */
  2671.  
  2672.     maxx = lmaxx; maxy = lmaxy;
  2673.  
  2674.     if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
  2675.     else if (row + down_back < 0)  illegalBlock |= 0x1;
  2676.     
  2677.     if (col + right_back + 7 > maxx) illegalBlock |= 0x2;
  2678.     else if (col + right_back < 0) illegalBlock |= 0x8;
  2679.  
  2680. #endif
  2681.  
  2682.   }
  2683.   /* Otherwise, block is NOT luminance block, ... */
  2684.  
  2685.   else {
  2686.  
  2687.     /* Construct motion vectors. */
  2688.  
  2689.     recon_right_back /= 2;
  2690.     recon_down_back /= 2;
  2691.     right_back = recon_right_back >> 1;
  2692.     down_back = recon_down_back >> 1;
  2693.     right_half_back = recon_right_back & 0x1;
  2694.     down_half_back = recon_down_back & 0x1;
  2695.  
  2696.     /* Establish row size. */
  2697.  
  2698.     row_size = vid_stream->mb_width << 3;
  2699.  
  2700.     /* Calculate row,col of upper left pixel in block. */
  2701.  
  2702.     row = mb_row << 3;
  2703.     col = mb_col << 3;
  2704.  
  2705. #ifdef LOOSE_MPEG
  2706.  
  2707.     /* Check for block illegality. */
  2708.  
  2709.     maxx = cmaxx; maxy = cmaxy;
  2710.  
  2711.     if (row + down_back + 7 > maxy) illegalBlock |= 0x4;
  2712.     else if (row + down_back < 0) illegalBlock |= 0x1;
  2713.  
  2714.     if (col + right_back + 7 > maxx) illegalBlock  |= 0x2;
  2715.     else if (col + right_back < 0) illegalBlock |= 0x8;
  2716.  
  2717. #endif
  2718.  
  2719.     /* If block is Cr block... */
  2720.  
  2721.     if (bnum == 4) {
  2722.  
  2723.       /* Set dest to Cr plane of current pict image. */
  2724.  
  2725.       dest = vid_stream->current->Cr;
  2726.  
  2727.       /*
  2728.        * If future frame exists, set future to Cr plane of future image.
  2729.        */
  2730.  
  2731.       if (vid_stream->future != NULL)
  2732.     future = vid_stream->future->Cr;
  2733.     }
  2734.     /* Otherwise, block is Cb block... */
  2735.  
  2736.     else {
  2737.  
  2738.       /* Set dest to Cb plane of current pict image. */
  2739.  
  2740.       dest = vid_stream->current->Cb;
  2741.  
  2742.       /*
  2743.        * If future frame exists, set future to Cb plane of future frame.
  2744.        */
  2745.  
  2746.       if (vid_stream->future != NULL)
  2747.     future = vid_stream->future->Cb;
  2748.     }
  2749.   }
  2750.  
  2751.   /* For each pixel in block do... */
  2752.  
  2753. #ifdef LOOSE_MPEG
  2754.  
  2755.   if (illegalBlock) {
  2756.     if (illegalBlock & 0x1) {
  2757.       row_start = 0;
  2758.       row_end = row+down_back+8;
  2759.       rfirst = rlast = 8 - row_end;
  2760.     }
  2761.     else if (illegalBlock & 0x4) {
  2762.       row_start = row + down_back;
  2763.       row_end = maxy+1;
  2764.       rlast = row_end - row_start - 1;
  2765.       rfirst = 0;
  2766.     }
  2767.     else {
  2768.       row_start = row+down_back;
  2769.       row_end = row_start+8;
  2770.       rfirst = 0;
  2771.     }
  2772.  
  2773.     if (illegalBlock & 0x8) {
  2774.       col_start = 0;
  2775.       col_end = col + right_back + 8;
  2776.       cfirst = clast = 8 - col_end;
  2777.     }
  2778.     else if (illegalBlock & 0x2) {
  2779.       col_start = col + right_back;
  2780.       col_end = maxx + 1;
  2781.       clast = col_end - col_start - 1;
  2782.       cfirst = 0;
  2783.     }
  2784.     else {
  2785.       col_start = col + right_back;
  2786.       col_end = col_start + 8;
  2787.       cfirst = 0;
  2788.     }
  2789.  
  2790.     for (rr = row_start; rr < row_end; rr++) {
  2791.       rindex1 = future + (rr * row_size) + col_start;
  2792.       index = dest + ((row + rfirst) * row_size) + col + cfirst;
  2793.       for (cc = col_start; cc < col_end; cc++) {
  2794.     *index++ = *rindex1++;
  2795.       }
  2796.     }
  2797.  
  2798.     if (illegalBlock & 0x1) {
  2799.       for (rr = rlast -1; rr >=0; rr--) {
  2800.     index = dest + ((row + rr) * row_size) + col;
  2801.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2802.     for (cc = 0; cc < 8; cc ++) {
  2803.       *index++ = *rindex1++;
  2804.     }
  2805.       }
  2806.     }
  2807.     else if (illegalBlock & 0x4) {
  2808.       for (rr = rlast+1; rr < 8; rr++) {
  2809.     index = dest + ((row + rr) * row_size) + col;
  2810.     rindex1 = dest + ((row + rlast) * row_size) + col;
  2811.     for (cc = 0; cc < 8; cc ++) {
  2812.       *index++ = *rindex1++;
  2813.     }
  2814.       }
  2815.     }
  2816.  
  2817.     if (illegalBlock & 0x2) {
  2818.       for (cc = clast+1; cc < 8; cc++) {
  2819.     index = dest + (row * row_size) + (col + cc);
  2820.     rindex1 = dest + (row * row_size) + (col + clast);
  2821.     for (rr = 0; rr < 8; rr++) {
  2822.       *index = *rindex1;
  2823.       index += row_size;
  2824.       rindex1 += row_size;
  2825.     }
  2826.       }
  2827.     }
  2828.     else if (illegalBlock & 0x8) {
  2829.       for (cc = clast-1; cc >= 0; cc--) {
  2830.     index = dest + (row * row_size) + (col + cc);
  2831.     rindex1 = dest + (row * row_size) + (col + clast);
  2832.     for (rr = 0; rr < 8; rr++) {
  2833.       *index = *rindex1;
  2834.       index += row_size;
  2835.       rindex1 += row_size;
  2836.     }
  2837.       }
  2838.     }
  2839.  
  2840.     if (!zflag) {
  2841.       for (rr = 0; rr < 8; rr++) {
  2842.     index = dest + (row*row_size) + col;
  2843.     blockvals = &(vid_stream->block.dct_recon[rr][0]);
  2844.     index[0] += blockvals[0];
  2845.     index[1] += blockvals[1];
  2846.     index[2] += blockvals[2];
  2847.     index[3] += blockvals[3];
  2848.     index[4] += blockvals[4];
  2849.     index[5] += blockvals[5];
  2850.     index[6] += blockvals[6];
  2851.     index[7] += blockvals[7];
  2852.       }
  2853.     }
  2854.   }
  2855.   else {
  2856.  
  2857. #endif
  2858.     
  2859.     index = dest + (row * row_size) + col;
  2860.     rindex1 = future + (row + down_back) * row_size + col + right_back;
  2861.  
  2862.     blockvals = &(vid_stream->block.dct_recon[0][0]);
  2863.  
  2864.     if ((!right_half_back) && (!down_half_back)) {
  2865.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2866.       if (!zflag)
  2867.     for (rr = 0; rr < 4; rr++) {
  2868.       index[0] = cm[(int) rindex1[0] + (int) blockvals[0]];
  2869.       index[1] = cm[(int) rindex1[1] + (int) blockvals[1]];
  2870.       index[2] = cm[(int) rindex1[2] + (int) blockvals[2]];
  2871.       index[3] = cm[(int) rindex1[3] + (int) blockvals[3]];
  2872.       index[4] = cm[(int) rindex1[4] + (int) blockvals[4]];
  2873.       index[5] = cm[(int) rindex1[5] + (int) blockvals[5]];
  2874.       index[6] = cm[(int) rindex1[6] + (int) blockvals[6]];
  2875.       index[7] = cm[(int) rindex1[7] + (int) blockvals[7]];
  2876.       index += row_size;
  2877.       rindex1 += row_size;
  2878.       
  2879.       index[0] = cm[(int) rindex1[0] + (int) blockvals[8]];
  2880.       index[1] = cm[(int) rindex1[1] + (int) blockvals[9]];
  2881.       index[2] = cm[(int) rindex1[2] + (int) blockvals[10]];
  2882.       index[3] = cm[(int) rindex1[3] + (int) blockvals[11]];
  2883.       index[4] = cm[(int) rindex1[4] + (int) blockvals[12]];
  2884.       index[5] = cm[(int) rindex1[5] + (int) blockvals[13]];
  2885.       index[6] = cm[(int) rindex1[6] + (int) blockvals[14]];
  2886.       index[7] = cm[(int) rindex1[7] + (int) blockvals[15]];
  2887.       blockvals += 16;
  2888.       index += row_size;
  2889.       rindex1 += row_size;
  2890.     }
  2891.       else {
  2892.     if (right_back & 0x1) {
  2893.       /* No alignment, use bye copy */
  2894.       for (rr = 0; rr < 4; rr++) {
  2895.         index[0] = rindex1[0];
  2896.         index[1] = rindex1[1];
  2897.         index[2] = rindex1[2];
  2898.         index[3] = rindex1[3];
  2899.         index[4] = rindex1[4];
  2900.         index[5] = rindex1[5];
  2901.         index[6] = rindex1[6];
  2902.         index[7] = rindex1[7];
  2903.         index += row_size;
  2904.         rindex1 += row_size;
  2905.         
  2906.         index[0] = rindex1[0];
  2907.         index[1] = rindex1[1];
  2908.         index[2] = rindex1[2];
  2909.         index[3] = rindex1[3];
  2910.         index[4] = rindex1[4];
  2911.         index[5] = rindex1[5];
  2912.         index[6] = rindex1[6];
  2913.         index[7] = rindex1[7];
  2914.         index += row_size;
  2915.         rindex1 += row_size;
  2916.       }
  2917.     } else if (right_back & 0x2) {
  2918.       /* Half-word bit aligned, use 16 bit copy */
  2919.       short *src = (short *)rindex1;
  2920.       short *dest = (short *)index;
  2921.       row_size >>= 1;
  2922.       for (rr = 0; rr < 4; rr++) {
  2923.         dest[0] = src[0];
  2924.         dest[1] = src[1];
  2925.         dest[2] = src[2];
  2926.         dest[3] = src[3];
  2927.         dest += row_size;
  2928.         src += row_size;
  2929.         
  2930.         dest[0] = src[0];
  2931.         dest[1] = src[1];
  2932.         dest[2] = src[2];
  2933.         dest[3] = src[3];
  2934.         dest += row_size;
  2935.         src += row_size;
  2936.       }
  2937.     } else {
  2938.       /* Word aligned, use 32 bit copy */
  2939.       int *src = (int *)rindex1;
  2940.       int *dest = (int *)index;
  2941.       row_size >>= 2;
  2942.       for (rr = 0; rr < 4; rr++) {
  2943.         dest[0] = src[0];
  2944.         dest[1] = src[1];
  2945.         dest += row_size;
  2946.         src += row_size;
  2947.         
  2948.         dest[0] = src[0];
  2949.         dest[1] = src[1];
  2950.         dest += row_size;
  2951.         src += row_size;
  2952.       }
  2953.     }
  2954.       }
  2955.     } else {
  2956.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2957.       rindex2 = rindex1 + right_half_back + (down_half_back * row_size);
  2958.       if (!zflag)
  2959.     for (rr = 0; rr < 4; rr++) {
  2960.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[0]];
  2961.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[1]];
  2962.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[2]];
  2963.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[3]];
  2964.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[4]];
  2965.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[5]];
  2966.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[6]];
  2967.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[7]];
  2968.       index += row_size;
  2969.       rindex1 += row_size;
  2970.       rindex2 += row_size;
  2971.       
  2972.       index[0] = cm[((int) (rindex1[0] + rindex2[0]) >> 1) + blockvals[8]];
  2973.       index[1] = cm[((int) (rindex1[1] + rindex2[1]) >> 1) + blockvals[9]];
  2974.       index[2] = cm[((int) (rindex1[2] + rindex2[2]) >> 1) + blockvals[10]];
  2975.       index[3] = cm[((int) (rindex1[3] + rindex2[3]) >> 1) + blockvals[11]];
  2976.       index[4] = cm[((int) (rindex1[4] + rindex2[4]) >> 1) + blockvals[12]];
  2977.       index[5] = cm[((int) (rindex1[5] + rindex2[5]) >> 1) + blockvals[13]];
  2978.       index[6] = cm[((int) (rindex1[6] + rindex2[6]) >> 1) + blockvals[14]];
  2979.       index[7] = cm[((int) (rindex1[7] + rindex2[7]) >> 1) + blockvals[15]];
  2980.       blockvals += 16;
  2981.       index += row_size;
  2982.       rindex1 += row_size;
  2983.       rindex2 += row_size;
  2984.     }
  2985.       else
  2986.     for (rr = 0; rr < 4; rr++) {
  2987.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  2988.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  2989.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  2990.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  2991.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  2992.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  2993.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  2994.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  2995.       index += row_size;
  2996.       rindex1 += row_size;
  2997.       rindex2 += row_size;
  2998.       
  2999.       index[0] = (int) (rindex1[0] + rindex2[0]) >> 1;
  3000.       index[1] = (int) (rindex1[1] + rindex2[1]) >> 1;
  3001.       index[2] = (int) (rindex1[2] + rindex2[2]) >> 1;
  3002.       index[3] = (int) (rindex1[3] + rindex2[3]) >> 1;
  3003.       index[4] = (int) (rindex1[4] + rindex2[4]) >> 1;
  3004.       index[5] = (int) (rindex1[5] + rindex2[5]) >> 1;
  3005.       index[6] = (int) (rindex1[6] + rindex2[6]) >> 1;
  3006.       index[7] = (int) (rindex1[7] + rindex2[7]) >> 1;
  3007.       index += row_size;
  3008.       rindex1 += row_size;
  3009.       rindex2 += row_size;
  3010.     }
  3011.     }
  3012.  
  3013. #ifdef LOOSE_MPEG
  3014.   }
  3015. #endif
  3016.  
  3017. }
  3018.  
  3019.  
  3020. /*
  3021.  *--------------------------------------------------------------
  3022.  *
  3023.  * ReconBiMBlock --
  3024.  *
  3025.  *    Reconstructs bidirectionally predicted macroblocks.
  3026.  *
  3027.  * Results:
  3028.  *      None.
  3029.  *
  3030.  * Side effects:
  3031.  *      None.
  3032.  *
  3033.  *--------------------------------------------------------------
  3034.  */
  3035.  
  3036. static void
  3037. ReconBiMBlock(vid_stream, bnum, recon_right_for, recon_down_for,
  3038.           recon_right_back, recon_down_back, zflag)
  3039.   VidStream *vid_stream;
  3040.   int bnum, recon_right_for, recon_down_for, recon_right_back, recon_down_back;
  3041.   int zflag;
  3042. {
  3043.   int mb_row, mb_col, row, col, row_size, rr;
  3044.   unsigned char *dest, *past, *future;
  3045.   int right_for, down_for, right_half_for, down_half_for;
  3046.   int right_back, down_back, right_half_back, down_half_back;
  3047.   unsigned char *index, *rindex1, *bindex1;
  3048.   short int *blockvals;
  3049.   int forw_row_start, back_row_start, forw_col_start, back_col_start;
  3050.  
  3051. #ifdef LOOSE_MPEG
  3052.   int illegal_forw = 0;
  3053.   int illegal_back = 0;
  3054. #endif
  3055.  
  3056.   /* Calculate macroblock row and column from address. */
  3057.  
  3058.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  3059.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  3060.  
  3061.   /* If block is luminance block... */
  3062.  
  3063.   if (bnum < 4) {
  3064.  
  3065.     /*
  3066.      * Calculate right_for, down_for, right_half_for, down_half_for,
  3067.      * right_back, down_bakc, right_half_back, and down_half_back, motion
  3068.      * vectors.
  3069.      */
  3070.  
  3071.     right_for = recon_right_for >> 1;
  3072.     down_for = recon_down_for >> 1;
  3073.     right_half_for = recon_right_for & 0x1;
  3074.     down_half_for = recon_down_for & 0x1;
  3075.  
  3076.     right_back = recon_right_back >> 1;
  3077.     down_back = recon_down_back >> 1;
  3078.     right_half_back = recon_right_back & 0x1;
  3079.     down_half_back = recon_down_back & 0x1;
  3080.  
  3081.     /* Set dest to luminance plane of current pict image. */
  3082.  
  3083.     dest = vid_stream->current->luminance;
  3084.  
  3085.     /* If past frame exists, set past to luminance plane of past frame. */
  3086.  
  3087.     if (vid_stream->past != NULL)
  3088.       past = vid_stream->past->luminance;
  3089.  
  3090.     /*
  3091.      * If future frame exists, set future to luminance plane of future frame.
  3092.      */
  3093.  
  3094.     if (vid_stream->future != NULL)
  3095.       future = vid_stream->future->luminance;
  3096.  
  3097.     /* Establish row size. */
  3098.  
  3099.     row_size = (vid_stream->mb_width << 4);
  3100.  
  3101.     /* Calculate row,col of upper left pixel in block. */
  3102.  
  3103.     row = (mb_row << 4);
  3104.     col = (mb_col << 4);
  3105.     if (bnum > 1)
  3106.       row += 8;
  3107.     if (bnum & 0x01)
  3108.       col += 8;
  3109.  
  3110.     forw_col_start = col + right_for;
  3111.     forw_row_start = row + down_for;
  3112.  
  3113.     back_col_start = col + right_back;
  3114.     back_row_start = row + down_back;
  3115.  
  3116. #ifdef LOOSE_MPEG
  3117.  
  3118.     /* Check for illegal pred. blocks. */
  3119.  
  3120.  
  3121.     if (forw_col_start+8 > lmaxx) illegal_forw = 1;
  3122.     else if (forw_col_start < 0) illegal_forw = 1;
  3123.  
  3124.     if (forw_row_start+8 > lmaxy) illegal_forw = 1;
  3125.     else if (forw_row_start < 0) illegal_forw = 1;
  3126.  
  3127.     if (back_col_start+8 > lmaxx) illegal_back = 1;
  3128.     else if (back_col_start < 0) illegal_back = 1;
  3129.  
  3130.     if (back_row_start+8 > lmaxy) illegal_back = 1;
  3131.     else if (back_row_start < 0) illegal_back = 1;
  3132.  
  3133. #endif
  3134.  
  3135.   }
  3136.   /* Otherwise, block is NOT luminance block, ... */
  3137.  
  3138.   else {
  3139.  
  3140.     /* Construct motion vectors. */
  3141.  
  3142.     recon_right_for /= 2;
  3143.     recon_down_for /= 2;
  3144.     right_for = recon_right_for >> 1;
  3145.     down_for = recon_down_for >> 1;
  3146.     right_half_for = recon_right_for & 0x1;
  3147.     down_half_for = recon_down_for & 0x1;
  3148.  
  3149.     recon_right_back /= 2;
  3150.     recon_down_back /= 2;
  3151.     right_back = recon_right_back >> 1;
  3152.     down_back = recon_down_back >> 1;
  3153.     right_half_back = recon_right_back & 0x1;
  3154.     down_half_back = recon_down_back & 0x1;
  3155.  
  3156.     /* Establish row size. */
  3157.  
  3158.     row_size = (vid_stream->mb_width << 3);
  3159.  
  3160.     /* Calculate row,col of upper left pixel in block. */
  3161.  
  3162.     row = (mb_row << 3);
  3163.     col = (mb_col << 3);
  3164.  
  3165.     forw_col_start = col + right_for;
  3166.     forw_row_start = row + down_for;
  3167.  
  3168.     back_col_start = col + right_back;
  3169.     back_row_start = row + down_back;
  3170.  
  3171. #ifdef LOOSE_MPEG
  3172.  
  3173.     /* Check for illegal pred. blocks. */
  3174.  
  3175.     if (forw_col_start+8 > cmaxx) illegal_forw = 1;
  3176.     else if (forw_col_start < 0) illegal_forw = 1;
  3177.  
  3178.     if (forw_row_start+8 > cmaxy) illegal_forw = 1;
  3179.     else if (forw_row_start < 0) illegal_forw = 1;
  3180.  
  3181.     if (back_col_start+8 > cmaxx) illegal_back = 1;
  3182.     else if (back_col_start < 0) illegal_back = 1;
  3183.     
  3184.     if (back_row_start+8 > cmaxy) illegal_back = 1;
  3185.     else if (back_row_start < 0) illegal_back = 1;
  3186.  
  3187. #endif
  3188.     
  3189.     /* If block is Cr block... */
  3190.  
  3191.     if (bnum == 4) {
  3192.  
  3193.       /* Set dest to Cr plane of current pict image. */
  3194.  
  3195.       dest = vid_stream->current->Cr;
  3196.  
  3197.       /* If past frame exists, set past to Cr plane of past image. */
  3198.  
  3199.       if (vid_stream->past != NULL)
  3200.     past = vid_stream->past->Cr;
  3201.  
  3202.       /*
  3203.        * If future frame exists, set future to Cr plane of future image.
  3204.        */
  3205.  
  3206.       if (vid_stream->future != NULL)
  3207.     future = vid_stream->future->Cr;
  3208.     }
  3209.     /* Otherwise, block is Cb block... */
  3210.  
  3211.     else {
  3212.  
  3213.       /* Set dest to Cb plane of current pict image. */
  3214.  
  3215.       dest = vid_stream->current->Cb;
  3216.  
  3217.       /* If past frame exists, set past to Cb plane of past frame. */
  3218.  
  3219.       if (vid_stream->past != NULL)
  3220.     past = vid_stream->past->Cb;
  3221.  
  3222.       /*
  3223.        * If future frame exists, set future to Cb plane of future frame.
  3224.        */
  3225.  
  3226.       if (vid_stream->future != NULL)
  3227.     future = vid_stream->future->Cb;
  3228.     }
  3229.   }
  3230.  
  3231.   /* For each pixel in block... */
  3232.  
  3233.   index = dest + (row * row_size) + col;
  3234.  
  3235. #ifdef LOOSE_MPEG
  3236.   if (illegal_forw) 
  3237.     rindex1 = future + back_row_start * row_size + back_col_start;
  3238.   else 
  3239. #endif
  3240.     rindex1 = past + forw_row_start  * row_size + forw_col_start;
  3241.  
  3242. #ifdef LOOSE_MPEG
  3243.   if (illegal_back) 
  3244.     bindex1 = past + forw_row_start * row_size + forw_col_start;
  3245.   else 
  3246. #endif
  3247.     bindex1 = future + back_row_start * row_size + back_col_start;
  3248.  
  3249.   blockvals = (short int *) &(vid_stream->block.dct_recon[0][0]);
  3250.  
  3251.   {
  3252.   unsigned char *cm = cropTbl + MAX_NEG_CROP;
  3253.   if (!zflag)
  3254.     for (rr = 0; rr < 4; rr++) {
  3255.       index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[0]];
  3256.       index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[1]];
  3257.       index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[2]];
  3258.       index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[3]];
  3259.       index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[4]];
  3260.       index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[5]];
  3261.       index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[6]];
  3262.       index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[7]];
  3263.       index += row_size;
  3264.       rindex1 += row_size;
  3265.       bindex1 += row_size;
  3266.  
  3267.       index[0] = cm[((int) (rindex1[0] + bindex1[0]) >> 1) + blockvals[8]];
  3268.       index[1] = cm[((int) (rindex1[1] + bindex1[1]) >> 1) + blockvals[9]];
  3269.       index[2] = cm[((int) (rindex1[2] + bindex1[2]) >> 1) + blockvals[10]];
  3270.       index[3] = cm[((int) (rindex1[3] + bindex1[3]) >> 1) + blockvals[11]];
  3271.       index[4] = cm[((int) (rindex1[4] + bindex1[4]) >> 1) + blockvals[12]];
  3272.       index[5] = cm[((int) (rindex1[5] + bindex1[5]) >> 1) + blockvals[13]];
  3273.       index[6] = cm[((int) (rindex1[6] + bindex1[6]) >> 1) + blockvals[14]];
  3274.       index[7] = cm[((int) (rindex1[7] + bindex1[7]) >> 1) + blockvals[15]];
  3275.       blockvals += 16;
  3276.       index += row_size;
  3277.       rindex1 += row_size;
  3278.       bindex1 += row_size;
  3279.     }
  3280.  
  3281.   else
  3282.     for (rr = 0; rr < 4; rr++) {
  3283.       index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
  3284.       index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
  3285.       index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
  3286.       index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
  3287.       index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
  3288.       index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
  3289.       index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
  3290.       index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
  3291.       index += row_size;
  3292.       rindex1 += row_size;
  3293.       bindex1 += row_size;
  3294.  
  3295.       index[0] = (int) (rindex1[0] + bindex1[0]) >> 1;
  3296.       index[1] = (int) (rindex1[1] + bindex1[1]) >> 1;
  3297.       index[2] = (int) (rindex1[2] + bindex1[2]) >> 1;
  3298.       index[3] = (int) (rindex1[3] + bindex1[3]) >> 1;
  3299.       index[4] = (int) (rindex1[4] + bindex1[4]) >> 1;
  3300.       index[5] = (int) (rindex1[5] + bindex1[5]) >> 1;
  3301.       index[6] = (int) (rindex1[6] + bindex1[6]) >> 1;
  3302.       index[7] = (int) (rindex1[7] + bindex1[7]) >> 1;
  3303.       index += row_size;
  3304.       rindex1 += row_size;
  3305.       bindex1 += row_size;
  3306.     }
  3307.   }
  3308. }
  3309.  
  3310. /*
  3311.  *--------------------------------------------------------------
  3312.  *
  3313.  * ProcessSkippedPFrameMBlocks --
  3314.  *
  3315.  *    Processes skipped macroblocks in P frames.
  3316.  *
  3317.  * Results:
  3318.  *    Calculates pixel values for luminance, Cr, and Cb planes
  3319.  *      in current pict image for skipped macroblocks.
  3320.  *
  3321.  * Side effects:
  3322.  *    Pixel values in pict image changed.
  3323.  *
  3324.  *--------------------------------------------------------------
  3325.  */
  3326.  
  3327. static void
  3328. ProcessSkippedPFrameMBlocks(vid_stream)
  3329.   VidStream *vid_stream;
  3330. {
  3331.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  3332.   int addr, row_incr, half_row_incr, crow, ccol;
  3333.   int *dest, *src, *dest1, *src1;
  3334.  
  3335.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  3336.  
  3337.   row_size = vid_stream->mb_width << 4;
  3338.   half_row = (row_size >> 1);
  3339.   row_incr = row_size >> 2;
  3340.   half_row_incr = half_row >> 2;
  3341.  
  3342.   /* For each skipped macroblock, do... */
  3343.  
  3344.   for (addr = vid_stream->mblock.past_mb_addr + 1;
  3345.        addr < vid_stream->mblock.mb_address; addr++) {
  3346.  
  3347.     /* Calculate macroblock row and col. */
  3348.  
  3349.     mb_row = addr / vid_stream->mb_width;
  3350.     mb_col = addr % vid_stream->mb_width;
  3351.  
  3352.     /* Calculate upper left pixel row,col for luminance plane. */
  3353.  
  3354.     row = mb_row << 4;
  3355.     col = mb_col << 4;
  3356.  
  3357.  
  3358.     /* For each row in macroblock luminance plane... */
  3359.  
  3360.     dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3361.     src = (int *)(vid_stream->future->luminance + (row * row_size) + col);
  3362.  
  3363.     for (rr = 0; rr < 8; rr++) {
  3364.  
  3365.       /* Copy pixel values from last I or P picture. */
  3366.  
  3367.       dest[0] = src[0];
  3368.       dest[1] = src[1];
  3369.       dest[2] = src[2];
  3370.       dest[3] = src[3];
  3371.       dest += row_incr;
  3372.       src += row_incr;
  3373.  
  3374.       dest[0] = src[0];
  3375.       dest[1] = src[1];
  3376.       dest[2] = src[2];
  3377.       dest[3] = src[3];
  3378.       dest += row_incr;
  3379.       src += row_incr;
  3380.     }
  3381.  
  3382.     /*
  3383.      * Divide row,col to get upper left pixel of macroblock in Cr and Cb
  3384.      * planes.
  3385.      */
  3386.  
  3387.     crow = row >> 1;
  3388.     ccol = col >> 1;
  3389.  
  3390.     /* For each row in Cr, and Cb planes... */
  3391.  
  3392.     dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3393.     src = (int *)(vid_stream->future->Cr + (crow * half_row) + ccol);
  3394.     dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3395.     src1 = (int *)(vid_stream->future->Cb + (crow * half_row) + ccol);
  3396.  
  3397.     for (rr = 0; rr < 4; rr++) {
  3398.  
  3399.       /* Copy pixel values from last I or P picture. */
  3400.  
  3401.       dest[0] = src[0];
  3402.       dest[1] = src[1];
  3403.  
  3404.       dest1[0] = src1[0];
  3405.       dest1[1] = src1[1];
  3406.  
  3407.       dest += half_row_incr;
  3408.       src += half_row_incr;
  3409.       dest1 += half_row_incr;
  3410.       src1 += half_row_incr;
  3411.  
  3412.       dest[0] = src[0];
  3413.       dest[1] = src[1];
  3414.  
  3415.       dest1[0] = src1[0];
  3416.       dest1[1] = src1[1];
  3417.  
  3418.       dest += half_row_incr;
  3419.       src += half_row_incr;
  3420.       dest1 += half_row_incr;
  3421.       src1 += half_row_incr;
  3422.     }
  3423.  
  3424.     if (ditherType == MBORDERED_DITHER) {
  3425.       MBOrderedDitherDisplayCopy(vid_stream, addr,
  3426.                  1, 0, 0, 0, 0, 0,
  3427.                  vid_stream->future->display,
  3428.                  (unsigned char *) NULL);
  3429.       ditherFlags[addr] = 0;
  3430.     }
  3431.   }
  3432.  
  3433.   vid_stream->mblock.recon_right_for_prev = 0;
  3434.   vid_stream->mblock.recon_down_for_prev = 0;
  3435. }
  3436.  
  3437.  
  3438.  
  3439.  
  3440. /*
  3441.  *--------------------------------------------------------------
  3442.  *
  3443.  * ProcessSkippedBFrameMBlocks --
  3444.  *
  3445.  *    Processes skipped macroblocks in B frames.
  3446.  *
  3447.  * Results:
  3448.  *    Calculates pixel values for luminance, Cr, and Cb planes
  3449.  *      in current pict image for skipped macroblocks.
  3450.  *
  3451.  * Side effects:
  3452.  *    Pixel values in pict image changed.
  3453.  *
  3454.  *--------------------------------------------------------------
  3455.  */
  3456.  
  3457. static void
  3458. ProcessSkippedBFrameMBlocks(vid_stream)
  3459.   VidStream *vid_stream;
  3460. {
  3461.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  3462.   int right_half_for, down_half_for, c_right_half_for, c_down_half_for;
  3463.   int right_half_back, down_half_back, c_right_half_back, c_down_half_back;
  3464.   int addr, right_for, down_for;
  3465.   int recon_right_for, recon_down_for;
  3466.   int recon_right_back, recon_down_back;
  3467.   int right_back, down_back;
  3468.   int c_right_for, c_down_for;
  3469.   int c_right_back, c_down_back;
  3470.   unsigned char forw_lum[256];
  3471.   unsigned char forw_cr[64], forw_cb[64];
  3472.   unsigned char back_lum[256], back_cr[64], back_cb[64];
  3473.   int row_incr, half_row_incr;
  3474.   int ccol, crow;
  3475.  
  3476.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  3477.  
  3478.   row_size = vid_stream->mb_width << 4;
  3479.   half_row = (row_size >> 1);
  3480.   row_incr = row_size >> 2;
  3481.   half_row_incr =  half_row >> 2;
  3482.  
  3483.   /* Establish motion vector codes based on full pixel flag. */
  3484.  
  3485.   if (vid_stream->picture.full_pel_forw_vector) {
  3486.     recon_right_for = vid_stream->mblock.recon_right_for_prev << 1;
  3487.     recon_down_for = vid_stream->mblock.recon_down_for_prev << 1;
  3488.   } else {
  3489.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  3490.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  3491.   }
  3492.  
  3493.   if (vid_stream->picture.full_pel_back_vector) {
  3494.     recon_right_back = vid_stream->mblock.recon_right_back_prev << 1;
  3495.     recon_down_back = vid_stream->mblock.recon_down_back_prev << 1;
  3496.   } else {
  3497.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  3498.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  3499.   }
  3500.  
  3501.  
  3502.   /* If only one motion vector, do display copy, else do full
  3503.      calculation. 
  3504.   */
  3505.  
  3506.   if (ditherType == MBORDERED_DITHER) {
  3507.     if (vid_stream->mblock.bpict_past_forw &&
  3508.     !vid_stream->mblock.bpict_past_back) {
  3509.       for (addr = vid_stream->mblock.past_mb_addr+1;
  3510.        addr < vid_stream->mblock.mb_address; addr++) {
  3511.     
  3512.     MBOrderedDitherDisplayCopy(vid_stream, addr,
  3513.                    1, recon_right_for, recon_down_for,
  3514.                  0, 0, 0, vid_stream->past->display,
  3515.                    vid_stream->future->display);
  3516.     ditherFlags[addr] = 0;
  3517.       }
  3518.       return;
  3519.     }
  3520.     if (vid_stream->mblock.bpict_past_back && 
  3521.     !vid_stream->mblock.bpict_past_forw) {
  3522.       for (addr = vid_stream->mblock.past_mb_addr+1;
  3523.        addr < vid_stream->mblock.mb_address; addr++) {
  3524.     
  3525.     MBOrderedDitherDisplayCopy(vid_stream, addr,
  3526.                    0, 0, 0,
  3527.                    1, recon_right_back, recon_down_back,
  3528.                    vid_stream->past->display, vid_stream->future->display);
  3529.     ditherFlags[addr] = 0;
  3530.       }
  3531.       return;
  3532.     }
  3533.   }
  3534.  
  3535.   /* Calculate motion vectors. */
  3536.   
  3537.   if (vid_stream->mblock.bpict_past_forw) {
  3538.     right_for = recon_right_for >> 1;
  3539.     down_for = recon_down_for >> 1;
  3540.     right_half_for = recon_right_for & 0x1;
  3541.     down_half_for = recon_down_for & 0x1;
  3542.     
  3543.     recon_right_for /= 2;
  3544.     recon_down_for /= 2;
  3545.     c_right_for = recon_right_for >> 1;
  3546.     c_down_for = recon_down_for >> 1;
  3547.     c_right_half_for = recon_right_for & 0x1;
  3548.     c_down_half_for = recon_down_for & 0x1;
  3549.     
  3550.   }
  3551.   if (vid_stream->mblock.bpict_past_back) {
  3552.     right_back = recon_right_back >> 1;
  3553.     down_back = recon_down_back >> 1;
  3554.     right_half_back = recon_right_back & 0x1;
  3555.     down_half_back = recon_down_back & 0x1;
  3556.     
  3557.     recon_right_back /= 2;
  3558.     recon_down_back /= 2;
  3559.     c_right_back = recon_right_back >> 1;
  3560.     c_down_back = recon_down_back >> 1;
  3561.     c_right_half_back = recon_right_back & 0x1;
  3562.     c_down_half_back = recon_down_back & 0x1;
  3563.     
  3564.   }
  3565.   /* For each skipped macroblock, do... */
  3566.   
  3567.   for (addr = vid_stream->mblock.past_mb_addr + 1;
  3568.        addr < vid_stream->mblock.mb_address; addr++) {
  3569.     
  3570.     /* Calculate macroblock row and col. */
  3571.     
  3572.     mb_row = addr / vid_stream->mb_width;
  3573.     mb_col = addr % vid_stream->mb_width;
  3574.     
  3575.     /* Calculate upper left pixel row,col for luminance plane. */
  3576.     
  3577.     row = mb_row << 4;
  3578.     col = mb_col << 4;
  3579.     crow = row / 2;
  3580.     ccol = col / 2;
  3581.     
  3582.     /* If forward predicted, calculate prediction values. */
  3583.     
  3584.     if (vid_stream->mblock.bpict_past_forw) {
  3585.       
  3586.       ReconSkippedBlock(vid_stream->past->luminance, forw_lum,
  3587.             row, col, row_size, right_for, down_for,
  3588.             right_half_for, down_half_for, 16);
  3589.       ReconSkippedBlock(vid_stream->past->Cr, forw_cr, crow,
  3590.             ccol, half_row,
  3591.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  3592.       ReconSkippedBlock(vid_stream->past->Cb, forw_cb, crow,
  3593.             ccol, half_row,
  3594.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  3595.     }
  3596.     /* If back predicted, calculate prediction values. */
  3597.     
  3598.     if (vid_stream->mblock.bpict_past_back) {
  3599.       ReconSkippedBlock(vid_stream->future->luminance, back_lum,
  3600.             row, col, row_size, right_back, down_back,
  3601.             right_half_back, down_half_back, 16);
  3602.       ReconSkippedBlock(vid_stream->future->Cr, back_cr, crow,
  3603.             ccol, half_row,
  3604.             c_right_back, c_down_back,
  3605.             c_right_half_back, c_down_half_back, 8);
  3606.       ReconSkippedBlock(vid_stream->future->Cb, back_cb, crow,
  3607.             ccol, half_row,
  3608.             c_right_back, c_down_back,
  3609.             c_right_half_back, c_down_half_back, 8);
  3610.     }
  3611.     if (vid_stream->mblock.bpict_past_forw &&
  3612.     !vid_stream->mblock.bpict_past_back) {
  3613.       
  3614.       int *dest, *dest1;
  3615.       int *src, *src1;
  3616.       dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3617.       src = (int *)forw_lum;
  3618.       
  3619.       for (rr = 0; rr < 16; rr++) {
  3620.     
  3621.     /* memcpy(dest, forw_lum+(rr<<4), 16);  */
  3622.     dest[0] = src[0];
  3623.     dest[1] = src[1];
  3624.     dest[2] = src[2];
  3625.     dest[3] = src[3];
  3626.     dest += row_incr;
  3627.     src += 4;
  3628.       }
  3629.       
  3630.       dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3631.       dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3632.       src = (int *)forw_cr;
  3633.       src1 = (int *)forw_cb;
  3634.       
  3635.       for (rr = 0; rr < 8; rr++) {
  3636.     /*
  3637.      * memcpy(dest, forw_cr+(rr<<3), 8); memcpy(dest1, forw_cb+(rr<<3),
  3638.      * 8);
  3639.      */
  3640.     
  3641.     dest[0] = src[0];
  3642.     dest[1] = src[1];
  3643.     
  3644.     dest1[0] = src1[0];
  3645.     dest1[1] = src1[1];
  3646.     
  3647.     dest += half_row_incr;
  3648.     dest1 += half_row_incr;
  3649.     src += 2;
  3650.     src1 += 2;
  3651.       }
  3652.     } else if (vid_stream->mblock.bpict_past_back &&
  3653.            !vid_stream->mblock.bpict_past_forw) {
  3654.       
  3655.       int *src, *src1;
  3656.       int *dest, *dest1;
  3657.       dest = (int *)(vid_stream->current->luminance + (row * row_size) + col);
  3658.       src = (int *)back_lum;
  3659.       
  3660.       for (rr = 0; rr < 16; rr++) {
  3661.     dest[0] = src[0];
  3662.     dest[1] = src[1];
  3663.     dest[2] = src[2];
  3664.     dest[3] = src[3];
  3665.     dest += row_incr;
  3666.     src += 4;
  3667.       }
  3668.       
  3669.       
  3670.       dest = (int *)(vid_stream->current->Cr + (crow * half_row) + ccol);
  3671.       dest1 = (int *)(vid_stream->current->Cb + (crow * half_row) + ccol);
  3672.       src = (int *)back_cr;
  3673.       src1 = (int *)back_cb;
  3674.       
  3675.       for (rr = 0; rr < 8; rr++) {
  3676.     /*
  3677.      * memcpy(dest, back_cr+(rr<<3), 8); memcpy(dest1, back_cb+(rr<<3),
  3678.      * 8);
  3679.      */
  3680.     
  3681.     dest[0] = src[0];
  3682.     dest[1] = src[1];
  3683.     
  3684.     dest1[0] = src1[0];
  3685.     dest1[1] = src1[1];
  3686.     
  3687.     dest += half_row_incr;
  3688.     dest1 += half_row_incr;
  3689.     src += 2;
  3690.     src1 += 2;
  3691.       }
  3692.     } else {
  3693.       
  3694.       unsigned char *src1, *src2, *src1a, *src2a;
  3695.       unsigned char *dest, *dest1;
  3696.       dest = vid_stream->current->luminance + (row * row_size) + col;
  3697.       src1 = forw_lum;
  3698.       src2 = back_lum;
  3699.       
  3700.       for (rr = 0; rr < 16; rr++) {
  3701.     dest[0] = (int) (src1[0] + src2[0]) >> 1;
  3702.     dest[1] = (int) (src1[1] + src2[1]) >> 1;
  3703.     dest[2] = (int) (src1[2] + src2[2]) >> 1;
  3704.     dest[3] = (int) (src1[3] + src2[3]) >> 1;
  3705.     dest[4] = (int) (src1[4] + src2[4]) >> 1;
  3706.     dest[5] = (int) (src1[5] + src2[5]) >> 1;
  3707.     dest[6] = (int) (src1[6] + src2[6]) >> 1;
  3708.     dest[7] = (int) (src1[7] + src2[7]) >> 1;
  3709.     dest[8] = (int) (src1[8] + src2[8]) >> 1;
  3710.     dest[9] = (int) (src1[9] + src2[9]) >> 1;
  3711.     dest[10] = (int) (src1[10] + src2[10]) >> 1;
  3712.     dest[11] = (int) (src1[11] + src2[11]) >> 1;
  3713.     dest[12] = (int) (src1[12] + src2[12]) >> 1;
  3714.     dest[13] = (int) (src1[13] + src2[13]) >> 1;
  3715.     dest[14] = (int) (src1[14] + src2[14]) >> 1;
  3716.     dest[15] = (int) (src1[15] + src2[15]) >> 1;
  3717.     dest += row_size;
  3718.     src1 += 16;
  3719.     src2 += 16;
  3720.       }
  3721.       
  3722.       
  3723.       dest = vid_stream->current->Cr + (crow * half_row) + ccol;
  3724.       dest1 = vid_stream->current->Cb + (crow * half_row) + ccol;
  3725.       src1 = forw_cr;
  3726.       src2 = back_cr;
  3727.       src1a = forw_cb;
  3728.       src2a = back_cb;
  3729.       
  3730.       for (rr = 0; rr < 8; rr++) {
  3731.     dest[0] = (int) (src1[0] + src2[0]) >> 1;
  3732.     dest[1] = (int) (src1[1] + src2[1]) >> 1;
  3733.     dest[2] = (int) (src1[2] + src2[2]) >> 1;
  3734.     dest[3] = (int) (src1[3] + src2[3]) >> 1;
  3735.     dest[4] = (int) (src1[4] + src2[4]) >> 1;
  3736.     dest[5] = (int) (src1[5] + src2[5]) >> 1;
  3737.     dest[6] = (int) (src1[6] + src2[6]) >> 1;
  3738.     dest[7] = (int) (src1[7] + src2[7]) >> 1;
  3739.     dest += half_row;
  3740.     src1 += 8;
  3741.     src2 += 8;
  3742.     
  3743.     dest1[0] = (int) (src1a[0] + src2a[0]) >> 1;
  3744.     dest1[1] = (int) (src1a[1] + src2a[1]) >> 1;
  3745.     dest1[2] = (int) (src1a[2] + src2a[2]) >> 1;
  3746.     dest1[3] = (int) (src1a[3] + src2a[3]) >> 1;
  3747.     dest1[4] = (int) (src1a[4] + src2a[4]) >> 1;
  3748.     dest1[5] = (int) (src1a[5] + src2a[5]) >> 1;
  3749.     dest1[6] = (int) (src1a[6] + src2a[6]) >> 1;
  3750.     dest1[7] = (int) (src1a[7] + src2a[7]) >> 1;
  3751.     dest1 += half_row;
  3752.     src1a += 8;
  3753.     src2a += 8;
  3754.       }
  3755.     }
  3756.     
  3757.     if (ditherType == MBORDERED_DITHER) {
  3758.       ditherFlags[addr] = 1;
  3759.     }
  3760.   }
  3761. }
  3762.  
  3763.  
  3764.  
  3765.  
  3766. /*
  3767.  *--------------------------------------------------------------
  3768.  *
  3769.  * ReconSkippedBlock --
  3770.  *
  3771.  *    Reconstructs predictive block for skipped macroblocks
  3772.  *      in B Frames.
  3773.  *
  3774.  * Results:
  3775.  *    No return values.
  3776.  *
  3777.  * Side effects:
  3778.  *    None.
  3779.  *
  3780.  *--------------------------------------------------------------
  3781.  */
  3782.  
  3783. static void
  3784. ReconSkippedBlock(source, dest, row, col, row_size,
  3785.           right, down, right_half, down_half, width)
  3786.   unsigned char *source;
  3787.   unsigned char *dest;
  3788.   int row, col, row_size, right, down, right_half, down_half, width;
  3789. {
  3790.   int rr;
  3791.   unsigned char *source2;
  3792.  
  3793.   source += ((row + down) * row_size) + col + right;
  3794.  
  3795.   if (width == 16) {
  3796.     if ((!right_half) && (!down_half)) {
  3797.     if (right & 0x1) {
  3798.       /* No alignment, use bye copy */
  3799.       for (rr = 0; rr < 16; rr++) {
  3800.         dest[0] = source[0];
  3801.         dest[1] = source[1];
  3802.         dest[2] = source[2];
  3803.         dest[3] = source[3];
  3804.         dest[4] = source[4];
  3805.         dest[5] = source[5];
  3806.         dest[6] = source[6];
  3807.         dest[7] = source[7];
  3808.         dest[8] = source[8];
  3809.         dest[9] = source[9];
  3810.         dest[10] = source[10];
  3811.         dest[11] = source[11];
  3812.         dest[12] = source[12];
  3813.         dest[13] = source[13];
  3814.         dest[14] = source[14];
  3815.         dest[15] = source[15];
  3816.         dest += 16;
  3817.         source += row_size;
  3818.       }
  3819.     } else if (right & 0x2) {
  3820.       /* Half-word bit aligned, use 16 bit copy */
  3821.       short *src = (short *)source;
  3822.       short *d = (short *)dest;
  3823.       row_size >>= 1;
  3824.       for (rr = 0; rr < 16; rr++) {
  3825.         d[0] = src[0];
  3826.         d[1] = src[1];
  3827.         d[2] = src[2];
  3828.         d[3] = src[3];
  3829.         d[4] = src[4];
  3830.         d[5] = src[5];
  3831.         d[6] = src[6];
  3832.         d[7] = src[7];
  3833.         d += 8;
  3834.         src += row_size;
  3835.       }
  3836.     } else {
  3837.       /* Word aligned, use 32 bit copy */
  3838.       int *src = (int *)source;
  3839.       int *d = (int *)dest;
  3840.       row_size >>= 2;
  3841.       for (rr = 0; rr < 16; rr++) {
  3842.         d[0] = src[0];
  3843.         d[1] = src[1];
  3844.         d[2] = src[2];
  3845.         d[3] = src[3];
  3846.         d += 4;
  3847.         src += row_size;
  3848.       }
  3849.     }
  3850.     } else {
  3851.       source2 = source + right_half + (row_size * down_half);
  3852.       for (rr = 0; rr < width; rr++) {
  3853.     dest[0] = (int) (source[0] + source2[0]) >> 1;
  3854.     dest[1] = (int) (source[1] + source2[1]) >> 1;
  3855.     dest[2] = (int) (source[2] + source2[2]) >> 1;
  3856.     dest[3] = (int) (source[3] + source2[3]) >> 1;
  3857.     dest[4] = (int) (source[4] + source2[4]) >> 1;
  3858.     dest[5] = (int) (source[5] + source2[5]) >> 1;
  3859.     dest[6] = (int) (source[6] + source2[6]) >> 1;
  3860.     dest[7] = (int) (source[7] + source2[7]) >> 1;
  3861.     dest[8] = (int) (source[8] + source2[8]) >> 1;
  3862.     dest[9] = (int) (source[9] + source2[9]) >> 1;
  3863.     dest[10] = (int) (source[10] + source2[10]) >> 1;
  3864.     dest[11] = (int) (source[11] + source2[11]) >> 1;
  3865.     dest[12] = (int) (source[12] + source2[12]) >> 1;
  3866.     dest[13] = (int) (source[13] + source2[13]) >> 1;
  3867.     dest[14] = (int) (source[14] + source2[14]) >> 1;
  3868.     dest[15] = (int) (source[15] + source2[15]) >> 1;
  3869.     dest += width;
  3870.     source += row_size;
  3871.     source2 += row_size;
  3872.       }
  3873.     }
  3874.   } else {            /* (width == 8) */
  3875.     assert(width == 8);
  3876.     if ((!right_half) && (!down_half)) {
  3877.       if (right & 0x1) {
  3878.     for (rr = 0; rr < width; rr++) {
  3879.       dest[0] = source[0];
  3880.       dest[1] = source[1];
  3881.       dest[2] = source[2];
  3882.       dest[3] = source[3];
  3883.       dest[4] = source[4];
  3884.       dest[5] = source[5];
  3885.       dest[6] = source[6];
  3886.       dest[7] = source[7];
  3887.       dest += 8;
  3888.       source += row_size;
  3889.     }
  3890.       } else if (right & 0x02) {
  3891.     short *d = (short *)dest;
  3892.     short *src = (short *)source;
  3893.     row_size >>= 1;
  3894.     for (rr = 0; rr < width; rr++) {
  3895.       d[0] = src[0];
  3896.       d[1] = src[1];
  3897.       d[2] = src[2];
  3898.       d[3] = src[3];
  3899.       d += 4;
  3900.       src += row_size;
  3901.     }
  3902.       } else {
  3903.     int *d = (int *)dest;
  3904.     int *src = (int *)source;
  3905.     row_size >>= 2;
  3906.     for (rr = 0; rr < width; rr++) {
  3907.       d[0] = src[0];
  3908.       d[1] = src[1];
  3909.       d += 2;
  3910.       src += row_size;
  3911.     }
  3912.       }
  3913.     } else {
  3914.       source2 = source + right_half + (row_size * down_half);
  3915.       for (rr = 0; rr < width; rr++) {
  3916.     dest[0] = (int) (source[0] + source2[0]) >> 1;
  3917.     dest[1] = (int) (source[1] + source2[1]) >> 1;
  3918.     dest[2] = (int) (source[2] + source2[2]) >> 1;
  3919.     dest[3] = (int) (source[3] + source2[3]) >> 1;
  3920.     dest[4] = (int) (source[4] + source2[4]) >> 1;
  3921.     dest[5] = (int) (source[5] + source2[5]) >> 1;
  3922.     dest[6] = (int) (source[6] + source2[6]) >> 1;
  3923.     dest[7] = (int) (source[7] + source2[7]) >> 1;
  3924.     dest += width;
  3925.     source += row_size;
  3926.     source2 += row_size;
  3927.       }
  3928.     }
  3929.   }
  3930. }
  3931.  
  3932.  
  3933.  
  3934. /*
  3935.  *--------------------------------------------------------------
  3936.  *
  3937.  * DoPictureDisplay --
  3938.  *
  3939.  *    Converts image from Lum, Cr, Cb to colormap space. Puts
  3940.  *      image in lum plane. Updates past and future frame
  3941.  *      pointers. Dithers image. Sends to display mechanism.
  3942.  *
  3943.  * Results:
  3944.  *    Pict image structure locked if displaying or if frame
  3945.  *      is needed as past or future reference.
  3946.  *
  3947.  * Side effects:
  3948.  *    Lum plane pummelled.
  3949.  *
  3950.  *--------------------------------------------------------------
  3951.  */
  3952.  
  3953. static void
  3954. DoPictureDisplay(vid_stream)
  3955.   VidStream *vid_stream;
  3956. {
  3957.  
  3958.   /* Convert to colormap space and dither. */
  3959.  
  3960.   DoDitherImage(vid_stream->current->luminance, vid_stream->current->Cr,
  3961.         vid_stream->current->Cb, vid_stream->current->display,
  3962.         vid_stream->mb_height * 16, vid_stream->mb_width * 16);
  3963.  
  3964.   /* Update past and future references if needed. */
  3965.  
  3966.   if ((vid_stream->picture.code_type == I_TYPE) || (vid_stream->picture.code_type == P_TYPE)) {
  3967.     if (vid_stream->future == NULL) {
  3968.       vid_stream->future = vid_stream->current;
  3969.       vid_stream->future->locked |= FUTURE_LOCK;
  3970.     } else {
  3971.       if (vid_stream->past != NULL) {
  3972.     vid_stream->past->locked &= ~PAST_LOCK;
  3973.       }
  3974.       vid_stream->past = vid_stream->future;
  3975.       vid_stream->past->locked &= ~FUTURE_LOCK;
  3976.       vid_stream->past->locked |= PAST_LOCK;
  3977.       vid_stream->future = vid_stream->current;
  3978.       vid_stream->future->locked |= FUTURE_LOCK;
  3979.       vid_stream->current = vid_stream->past;
  3980.       ExecuteDisplay(vid_stream);
  3981.     }
  3982.   } else
  3983.     ExecuteDisplay(vid_stream);
  3984.  
  3985. }
  3986.  
  3987.  
  3988.  
  3989. /*
  3990.  *--------------------------------------------------------------
  3991.  *
  3992.  * ToggleBFlag --
  3993.  *
  3994.  *    Called to set no b frame processing flag.
  3995.  *
  3996.  * Results:
  3997.  *      No_B_Flag flag is toggled from present value to opposite value.
  3998.  *
  3999.  * Side effects:
  4000.  *      None.
  4001.  *
  4002.  *--------------------------------------------------------------
  4003.  */
  4004.  
  4005. void
  4006. ToggleBFlag()
  4007. {
  4008.   if (No_B_Flag) {
  4009.     No_B_Flag = 0;
  4010.   } else
  4011.     No_B_Flag = 1;
  4012. }
  4013.  
  4014.  
  4015.  
  4016.  
  4017. /*
  4018.  *--------------------------------------------------------------
  4019.  *
  4020.  * TogglePFlag --
  4021.  *
  4022.  *    Called to set no p frame processing flag.
  4023.  *
  4024.  * Results:
  4025.  *      No_P_Flag flag is toggled from present value to opposite value.
  4026.  *
  4027.  * Side effects:
  4028.  *      None.
  4029.  *
  4030.  *--------------------------------------------------------------
  4031.  */
  4032.  
  4033. void
  4034. TogglePFlag()
  4035. {
  4036.   if (No_P_Flag) {
  4037.     No_P_Flag = 0;
  4038.   } else
  4039.     No_P_Flag = 1;
  4040. }
  4041.